diff --git a/.gitignore b/.gitignore index f0eaf94..812a5dc 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,6 @@ /build/ /logs/ /workdir/ +/dokka/ /src/main/resources/angular/static/* diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000..915ef22 Binary files /dev/null and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/build.gradle.kts b/build.gradle.kts index 5d9fc87..cff1bdd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,8 +4,8 @@ description = "Color Recipes Explorer" plugins { id("java") - id("org.jetbrains.kotlin.jvm") version "1.4.0" - id("org.jetbrains.dokka") version "1.4.0-rc" + id("org.jetbrains.kotlin.jvm") version "1.4.10" + id("org.jetbrains.dokka") version "1.4.10" 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" @@ -19,12 +19,16 @@ repositories { } dependencies { - implementation(platform("org.jetbrains.kotlin:kotlin-bom")) - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") - implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.4.10")) + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10") + implementation("org.jetbrains.kotlin:kotlin-reflect:1.4.10") implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.11.3") - testImplementation("org.jetbrains.kotlin:kotlin-test") - testImplementation("org.jetbrains.kotlin:kotlin-test-junit") + implementation("javax.xml.bind:jaxb-api:2.3.0") + 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("org.springframework.boot:spring-boot-starter-data-jpa:2.3.4.RELEASE") implementation("org.springframework.boot:spring-boot-starter-jdbc:2.3.4.RELEASE") @@ -33,28 +37,35 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-validation:2.3.4.RELEASE") implementation("org.springframework.boot:spring-boot-starter-security:2.3.4.RELEASE") implementation("org.springframework.boot:spring-boot-configuration-processor:2.3.4.RELEASE") - - testImplementation("org.springframework.boot:spring-boot-starter-test:2.3.4.RELEASE") - testImplementation("org.springframework.boot:spring-boot-test-autoconfigure:2.3.4.RELEASE") implementation("org.springframework.boot:spring-boot-devtools:2.3.4.RELEASE") - implementation("javax.xml.bind:jaxb-api:2.3.0") - 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("org.springframework:spring-test:5.1.6.RELEASE") - implementation("org.mockito:mockito-core:2.23.4") - implementation("org.junit.jupiter:junit-jupiter-api:5.3.2") + testImplementation("org.springframework:spring-test:5.1.6.RELEASE") + testImplementation("org.mockito:mockito-core:3.6.0") + testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.3.2") + testImplementation("org.springframework.boot:spring-boot-starter-test:2.3.4.RELEASE") + testImplementation("org.springframework.boot:spring-boot-test-autoconfigure:2.3.4.RELEASE") + testImplementation("org.jetbrains.kotlin:kotlin-test:1.4.10") + testImplementation("org.jetbrains.kotlin:kotlin-test-junit:1.4.10") +// testImplementation("io.mockk:mockk:1.10.2") runtimeOnly("com.h2database:h2:1.4.199") compileOnly("org.projectlombok:lombok:1.18.10") } java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_14 + targetCompatibility = JavaVersion.VERSION_14 +} + +sourceSets { + main { + java + kotlin + } + test { + kotlin + } } tasks.register("buildFrontend") { @@ -85,13 +96,13 @@ tasks.test { } tasks.withType { - options.compilerArgs.addAll(arrayOf("--release", "11")) + options.compilerArgs.addAll(arrayOf("--release", "14")) } tasks.withType { - kotlinOptions.jvmTarget = "11" + kotlinOptions.jvmTarget = "14" } tasks.dokkaHtml { - outputDirectory = "$buildDir/dokka" + outputDirectory.set(rootDir.resolve("dokka")) } diff --git a/src/main/frontend/src/app/app-routing.module.ts b/src/main/frontend/src/app/app-routing.module.ts index 3d0729e..a065f66 100644 --- a/src/main/frontend/src/app/app-routing.module.ts +++ b/src/main/frontend/src/app/app-routing.module.ts @@ -1,11 +1,27 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; +import {NgModule} from '@angular/core'; +import {Routes, RouterModule} from '@angular/router'; -const routes: Routes = [{ path: 'color', loadChildren: () => import('./modules/colors/colors.module').then(m => m.ColorsModule) }, { path: 'account', loadChildren: () => import('./modules/accounts/accounts.module').then(m => m.AccountsModule) }, { path: 'employee', loadChildren: () => import('./modules/employees/employees.module').then(m => m.EmployeesModule) }, { path: 'group', loadChildren: () => import('./modules/groups/groups.module').then(m => m.GroupsModule) }]; +const routes: Routes = [{ + path: 'color', + loadChildren: () => import('./modules/colors/colors.module').then(m => m.ColorsModule) +}, { + path: 'account', + loadChildren: () => import('./modules/accounts/accounts.module').then(m => m.AccountsModule) +}, { + path: 'employee', + loadChildren: () => import('./modules/employees/employees.module').then(m => m.EmployeesModule) +}, { + path: 'group', + loadChildren: () => import('./modules/groups/groups.module').then(m => m.GroupsModule) +}, { + path: 'inventory', + loadChildren: () => import('./modules/inventory/inventory.module').then(m => m.InventoryModule) +}]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) -export class AppRoutingModule { } +export class AppRoutingModule { +} diff --git a/src/main/frontend/src/app/modules/inventory/inventory-routing.module.ts b/src/main/frontend/src/app/modules/inventory/inventory-routing.module.ts new file mode 100644 index 0000000..b8b550f --- /dev/null +++ b/src/main/frontend/src/app/modules/inventory/inventory-routing.module.ts @@ -0,0 +1,19 @@ +import {NgModule} from '@angular/core'; +import {RouterModule, Routes} from '@angular/router'; + +import {InventoryComponent} from './inventory.component'; + +const routes: Routes = [{ + path: '', + component: InventoryComponent +}, { + path: 'materialtype', + loadChildren: () => import('./modules/materialtype/materialtype.module').then(m => m.MaterialtypeModule) +}]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class InventoryRoutingModule { +} diff --git a/src/main/frontend/src/app/modules/inventory/inventory.component.html b/src/main/frontend/src/app/modules/inventory/inventory.component.html new file mode 100644 index 0000000..cf6b65c --- /dev/null +++ b/src/main/frontend/src/app/modules/inventory/inventory.component.html @@ -0,0 +1,2 @@ + +test diff --git a/src/main/frontend/src/app/modules/inventory/inventory.component.sass b/src/main/frontend/src/app/modules/inventory/inventory.component.sass new file mode 100644 index 0000000..e69de29 diff --git a/src/main/frontend/src/app/modules/inventory/inventory.component.ts b/src/main/frontend/src/app/modules/inventory/inventory.component.ts new file mode 100644 index 0000000..838fa63 --- /dev/null +++ b/src/main/frontend/src/app/modules/inventory/inventory.component.ts @@ -0,0 +1,20 @@ +import {Component, OnInit} from '@angular/core'; +import {NavLink} from "../shared/components/nav/nav.component"; + +@Component({ + selector: 'cre-inventory', + templateUrl: './inventory.component.html', + styleUrls: ['./inventory.component.sass'] +}) +export class InventoryComponent implements OnInit { + navLinks: NavLink[] = [ + {route: 'materialtype', title: 'Types de produit', enabled: true} + ] + + constructor() { + } + + ngOnInit(): void { + } + +} diff --git a/src/main/frontend/src/app/modules/inventory/inventory.module.ts b/src/main/frontend/src/app/modules/inventory/inventory.module.ts new file mode 100644 index 0000000..b9cd251 --- /dev/null +++ b/src/main/frontend/src/app/modules/inventory/inventory.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { InventoryRoutingModule } from './inventory-routing.module'; +import { InventoryComponent } from './inventory.component'; +import {SharedModule} from "../shared/shared.module"; +import { MaterialtypeModule } from './modules/materialtype/materialtype.module'; + + +@NgModule({ + declarations: [InventoryComponent], + imports: [ + CommonModule, + InventoryRoutingModule, + SharedModule, + MaterialtypeModule + ] +}) +export class InventoryModule { } diff --git a/src/main/frontend/src/app/modules/inventory/modules/materialtype/materialtype-routing.module.ts b/src/main/frontend/src/app/modules/inventory/modules/materialtype/materialtype-routing.module.ts new file mode 100644 index 0000000..ea7378b --- /dev/null +++ b/src/main/frontend/src/app/modules/inventory/modules/materialtype/materialtype-routing.module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + + +const routes: Routes = []; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class MaterialtypeRoutingModule { } diff --git a/src/main/frontend/src/app/modules/inventory/modules/materialtype/materialtype.module.ts b/src/main/frontend/src/app/modules/inventory/modules/materialtype/materialtype.module.ts new file mode 100644 index 0000000..d1c3dc4 --- /dev/null +++ b/src/main/frontend/src/app/modules/inventory/modules/materialtype/materialtype.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { MaterialtypeRoutingModule } from './materialtype-routing.module'; +import { ListComponent } from './pages/list/list.component'; + + +@NgModule({ + declarations: [ListComponent], + imports: [ + CommonModule, + MaterialtypeRoutingModule + ] +}) +export class MaterialtypeModule { } diff --git a/src/main/frontend/src/app/modules/shared/components/header/header.component.ts b/src/main/frontend/src/app/modules/shared/components/header/header.component.ts index 39a5efe..b24369c 100644 --- a/src/main/frontend/src/app/modules/shared/components/header/header.component.ts +++ b/src/main/frontend/src/app/modules/shared/components/header/header.component.ts @@ -14,7 +14,7 @@ import {takeUntil} from "rxjs/operators"; export class HeaderComponent implements OnInit, OnDestroy { links: HeaderLink[] = [ // {route: 'color', title: 'Couleurs', enabled: true}, - // {route: 'inventory', title: 'Inventaire', enabled: true}, + {route: 'inventory', title: 'Inventaire', enabled: true}, new HeaderLink('employee', 'Employés', EmployeePermission.VIEW_EMPLOYEE), new HeaderLink('group', 'Groupes', EmployeePermission.VIEW_EMPLOYEE_GROUP), {route: 'account/login', title: 'Connexion', enabled: true}, diff --git a/src/main/frontend/src/app/modules/shared/components/nav/nav.component.html b/src/main/frontend/src/app/modules/shared/components/nav/nav.component.html new file mode 100644 index 0000000..e5d9439 --- /dev/null +++ b/src/main/frontend/src/app/modules/shared/components/nav/nav.component.html @@ -0,0 +1,11 @@ + diff --git a/src/main/frontend/src/app/modules/shared/components/nav/nav.component.sass b/src/main/frontend/src/app/modules/shared/components/nav/nav.component.sass new file mode 100644 index 0000000..c8a7b04 --- /dev/null +++ b/src/main/frontend/src/app/modules/shared/components/nav/nav.component.sass @@ -0,0 +1,11 @@ +@import '../../../../../custom-theme' + +nav + position: relative + z-index: 99 + padding-bottom: 1px + + a + opacity: 1 + font-size: 1.1em + color: white diff --git a/src/main/frontend/src/app/modules/shared/components/nav/nav.component.ts b/src/main/frontend/src/app/modules/shared/components/nav/nav.component.ts new file mode 100644 index 0000000..35c65c0 --- /dev/null +++ b/src/main/frontend/src/app/modules/shared/components/nav/nav.component.ts @@ -0,0 +1,72 @@ +import {Component, Input, OnDestroy, OnInit} from '@angular/core'; +import {Employee, EmployeePermission} from "../../model/employee"; +import {AccountService} from "../../../accounts/services/account.service"; +import {Router} from "@angular/router"; +import {takeUntil} from "rxjs/operators"; +import {AppState} from "../../app-state"; +import {Subject} from "rxjs"; + +@Component({ + selector: 'cre-nav', + templateUrl: './nav.component.html', + styleUrls: ['./nav.component.sass'] +}) +export class NavComponent implements OnInit, OnDestroy { + private _destroy$ = new Subject() + + @Input() links: NavLink [] = [] + + // links: NavLink[] = [ + // {route: 'materialtype', title: 'Types de produit', enabled: true} + // ] + _activeLink: string | null; + + constructor( + private accountService: AccountService, + private router: Router, + private appState: AppState + ) { + } + + ngOnInit(): void { + this.updateEnabledLinks(this.appState.authenticatedEmployee) + + this.appState.authenticatedUser$ + .pipe(takeUntil(this._destroy$)) + .subscribe({ + next: authentication => this.updateEnabledLinks(authentication.authenticatedUser) + }) + } + + ngOnDestroy(): void { + this._destroy$.next(true) + this._destroy$.complete() + } + + set activeLink(link: string) { + this._activeLink = link + this.router.navigate([link]) + } + + get activeLink() { + return this._activeLink + } + + private updateEnabledLinks(employee: Employee) { + this.links.forEach(l => { + if (l.requiredPermission) { + l.enabled = employee && employee.permissions.indexOf(l.requiredPermission) >= 0; + } + }) + } +} + +export class NavLink { + constructor( + public route: string, + public title: string, + public requiredPermission?: EmployeePermission, + public enabled = false + ) { + } +} diff --git a/src/main/frontend/src/app/modules/shared/model/materialtype.model.ts b/src/main/frontend/src/app/modules/shared/model/materialtype.model.ts new file mode 100644 index 0000000..e5122d6 --- /dev/null +++ b/src/main/frontend/src/app/modules/shared/model/materialtype.model.ts @@ -0,0 +1,9 @@ +export class MaterialType { + constructor( + public id: number, + public name: string, + public prefix: string, + public usePercentages: boolean + ) { + } +} diff --git a/src/main/frontend/src/app/modules/shared/shared.module.ts b/src/main/frontend/src/app/modules/shared/shared.module.ts index 8e08257..892881e 100644 --- a/src/main/frontend/src/app/modules/shared/shared.module.ts +++ b/src/main/frontend/src/app/modules/shared/shared.module.ts @@ -18,28 +18,30 @@ import {ConfirmBoxComponent} from './components/confirm-box/confirm-box.componen import {PermissionsListComponent} from './components/permissions-list/permissions-list.component'; import {MatChipsModule} from "@angular/material/chips"; import {PermissionsFieldComponent} from "./components/permissions-field/permissions-field.component"; +import { NavComponent } from './components/nav/nav.component'; @NgModule({ - declarations: [HeaderComponent, EmployeeInfoComponent, LabeledIconComponent, ConfirmBoxComponent, PermissionsListComponent, PermissionsFieldComponent], - exports: [ - CommonModule, - HttpClientModule, - HeaderComponent, - MatCardModule, - MatButtonModule, - MatFormFieldModule, - MatInputModule, - MatIconModule, - MatTableModule, - MatCheckboxModule, - MatListModule, - ReactiveFormsModule, - LabeledIconComponent, - ConfirmBoxComponent, - PermissionsListComponent, - PermissionsFieldComponent - ], + declarations: [HeaderComponent, EmployeeInfoComponent, LabeledIconComponent, ConfirmBoxComponent, PermissionsListComponent, PermissionsFieldComponent, NavComponent], + exports: [ + CommonModule, + HttpClientModule, + HeaderComponent, + MatCardModule, + MatButtonModule, + MatFormFieldModule, + MatInputModule, + MatIconModule, + MatTableModule, + MatCheckboxModule, + MatListModule, + ReactiveFormsModule, + LabeledIconComponent, + ConfirmBoxComponent, + PermissionsListComponent, + PermissionsFieldComponent, + NavComponent + ], imports: [ MatTabsModule, MatIconModule, diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/InitialDataLoader.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/InitialDataLoader.java new file mode 100644 index 0000000..7239ba8 --- /dev/null +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/InitialDataLoader.java @@ -0,0 +1,32 @@ +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 { + 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()); + } +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/LocaleConfiguration.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/LocaleConfiguration.java similarity index 96% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/LocaleConfiguration.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/LocaleConfiguration.java index c014431..d0ebca7 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/LocaleConfiguration.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/LocaleConfiguration.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.configuration; +package dev.fyloz.trial.colorrecipesexplorer.config; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/Preferences.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/Preferences.java similarity index 88% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/Preferences.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/Preferences.java index c3bfa13..6123b9f 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/Preferences.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/Preferences.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.core; +package dev.fyloz.trial.colorrecipesexplorer.config; import org.slf4j.Logger; import org.springframework.context.MessageSource; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/SpringConfiguration.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/SpringConfiguration.java similarity index 87% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/SpringConfiguration.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/SpringConfiguration.java index cc0f830..b265130 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/SpringConfiguration.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/SpringConfiguration.java @@ -1,11 +1,10 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.configuration; +package dev.fyloz.trial.colorrecipesexplorer.config; import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication; -import dev.fyloz.trial.colorrecipesexplorer.core.Preferences; -import dev.fyloz.trial.colorrecipesexplorer.core.model.config.CREProperties; -import dev.fyloz.trial.colorrecipesexplorer.core.model.config.MaterialTypeProperties; -import dev.fyloz.trial.colorrecipesexplorer.core.services.PasswordService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.files.FilesService; +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; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/config/CREProperties.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/properties/CREProperties.java similarity index 86% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/config/CREProperties.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/properties/CREProperties.java index 6ebfca5..3fd9f83 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/config/CREProperties.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/config/properties/CREProperties.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model.config; +package dev.fyloz.trial.colorrecipesexplorer.config.properties; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/InitialDataLoader.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/InitialDataLoader.java deleted file mode 100644 index 1a00ce9..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/InitialDataLoader.java +++ /dev/null @@ -1,43 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.configuration; - -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.config.MaterialTypeProperties; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService; -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 { - - private MaterialTypeService materialTypeService; - private MaterialTypeProperties materialTypeProperties; - - @Autowired - public InitialDataLoader(MaterialTypeService materialTypeService, MaterialTypeProperties materialTypeProperties) { - this.materialTypeService = materialTypeService; - this.materialTypeProperties = materialTypeProperties; - } - - @Override - public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { - for (MaterialType materialType : materialTypeProperties.getDefaults()) { - if (!materialTypeService.existsByName(materialType.getName())) { - materialTypeService.save(materialType); - } else { - MaterialType found = materialTypeService.getByName(materialType.getName()); - - found.setPrefix(materialType.getPrefix()); - found.setUsePercentages(materialType.isUsePercentages()); - - materialTypeService.update(found); - } - - materialTypeService.addDefault(materialType); - } - } -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityNotFoundException.kt b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityNotFoundException.kt deleted file mode 100644 index 3276adc..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityNotFoundException.kt +++ /dev/null @@ -1,19 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.exception.model - -import dev.fyloz.trial.colorrecipesexplorer.core.exception.RestException -import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel -import org.springframework.http.HttpStatus -import org.springframework.web.bind.annotation.ResponseStatus - -class EntityNotFoundException(modelType: Class, val identifierType: IdentifierType, val identifierName: String, val requestedId: Any) : ModelException(modelType) { - constructor(modelType: Class, identifierType: IdentifierType, requestedId: Any) : this(modelType, identifierType, identifierType.name, requestedId) -} - -@ResponseStatus(HttpStatus.NOT_FOUND) -class EntityNotFoundRestException(val value: Any) : RestException(HttpStatus.NOT_FOUND) { - override val exceptionMessage: String = "An entity could not be found with the given identifier" - - override fun buildBody(): RestExceptionBody = object : RestExceptionBody() { - val id = value - } -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/FileHandler.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/FileHandler.java deleted file mode 100644 index e8ffedd..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/FileHandler.java +++ /dev/null @@ -1,134 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.io.file; - -import dev.fyloz.trial.colorrecipesexplorer.core.Preferences; -import org.slf4j.Logger; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -@Deprecated(since = "1.3.0") -public class FileHandler { - - protected String name; - protected Logger logger = Preferences.logger; - - private FileContext context; - private FileExtension extension; - private File file; - - public FileHandler(String name, FileContext context, FileExtension extension) { - this.context = context; - this.extension = extension; - - setName(name); - file = getFile(); - } - - public boolean createFile() { - File parent = file.getParentFile(); - - if (!isValid()) { - if ((!parent.exists() || !parent.isDirectory()) && !parent.mkdirs()) { - return false; - } - - try { - logger.info("Création du fichier " + file.getAbsolutePath()); - return file.createNewFile(); - } catch (IOException e) { - logger.error("Erreur à la création d'un fichier", e); - return false; - } - } else { - logger.warn("Tentative de création du fichier existant " + file.getAbsolutePath()); - return false; - } - } - - public byte[] readFile() { - if (isValid()) { - try { - return Files.readAllBytes(getPath()); - } catch (IOException e) { - logger.error("Erreur lors de la lecture d'un fichier", e); - } - } - - logger.warn("Tentative de lecture du fichier invalide " + file.getAbsolutePath()); - return null; - } - - public boolean deleteFile() { - if (isValid()) { - logger.info("Suppression du fichier " + file.getAbsolutePath()); - return file.delete(); - } - - logger.warn("Tentative de suppression du fichier invalide " + file.getAbsolutePath()); - return false; - } - - public boolean isValid() { - return file.exists() && file.isFile(); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - - file = getFile(); - } - - public FileContext getContext() { - return context; - } - - public Path getPath() { - return Paths.get(String.format("%s/%s/%s%s", Preferences.uploadDirectory, context.getPath(), name, extension.getExtension())); - } - - public File getFile() { - return getPath().toFile(); - } - - public enum FileContext { - IMAGE("images"), - SIMDUT("simdut"), - PDF("pdf"), - OTHERS(""); - - private String path; - - FileContext(String path) { - this.path = path; - } - - public String getPath() { - return path; - } - } - - public enum FileExtension { - JPEG("jpeg"), - PDF("pdf"), - TEXT("txt"), - DATABASE("db"), - MARKDOWN("md"); - - private String extension; - - FileExtension(String extension) { - this.extension = extension; - } - - public String getExtension() { - return "." + extension; - } - } -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/ImageHandler.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/ImageHandler.java deleted file mode 100644 index 1ec4da2..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/ImageHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.io.file; - -import dev.fyloz.trial.colorrecipesexplorer.core.Preferences; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; - -import java.util.List; -import java.util.stream.Collectors; - -@Deprecated(since = "1.3.0") -public class ImageHandler extends FileHandler { - - public static final String IMAGES_LOCATION = Preferences.uploadDirectory + "/images"; - - private Recipe recipe; - private int index = 0; - private RecipeService recipeService; - - public ImageHandler(Recipe recipe, RecipeService recipeService) { - super(String.format("%s_%s", recipe.getId(), recipe.getName()), FileContext.IMAGE, FileExtension.JPEG); - - this.recipe = recipe; - this.recipeService = recipeService; - } - - public ImageHandler(String name, RecipeService recipeService) { - super(name.replace(".jpeg", ""), FileContext.IMAGE, FileExtension.JPEG); - - this.recipeService = recipeService; - - String[] nameParts = name.split("-"); - index = Integer.parseInt(nameParts[1].replace(".jpeg", "")); - } - - @Override - public boolean createFile() { - if (recipe != null) { - List existingImages = recipeService.getImageFiles(recipe); - - if (existingImages != null) { - List existingImagesIndexes = existingImages.stream().map(n -> Integer.parseInt(n.replace(name + "-", "").replace(".jpeg", ""))).collect(Collectors.toList()); - - while (existingImagesIndexes.contains(index)) { - index++; - } - } - - setName(String.format("%s-%s", getName(), index)); - return super.createFile(); - } - - logger.warn("Tentative de créer une image sans recette"); - return false; - } -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/AccountsModel.kt b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/AccountsModel.kt deleted file mode 100644 index e1c6b97..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/AccountsModel.kt +++ /dev/null @@ -1,179 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model - -import com.fasterxml.jackson.annotation.JsonIgnore -import com.fasterxml.jackson.annotation.JsonProperty -import org.hibernate.annotations.Fetch -import org.hibernate.annotations.FetchMode -import org.springframework.security.core.GrantedAuthority -import org.springframework.security.core.authority.SimpleGrantedAuthority -import java.time.LocalDateTime -import javax.persistence.* -import javax.validation.constraints.NotBlank -import javax.validation.constraints.NotNull -import javax.validation.constraints.Size -import kotlin.jvm.Transient - - -private const val EMPLOYEE_ID_NULL_MESSAGE = "Un numéro d'employé est requis" -private const val EMPLOYEE_LAST_NAME_EMPTY_MESSAGE = "Un nom est requis" -private const val EMPLOYEE_FIRST_NAME_EMPTY_MESSAGE = "Un prénom est requis" -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 -data class Employee( - @Id - @field:NotNull(message = EMPLOYEE_ID_NULL_MESSAGE) - override val id: Long, - - val firstName: String = "", - - val lastName: String = "", - - @JsonIgnore - val password: String = "", - - @JsonIgnore - val isDefaultGroupUser: Boolean = false, - - @JsonIgnore - val isSystemUser: Boolean = false, - - @field:ManyToOne - @Fetch(FetchMode.SELECT) - var group: EmployeeGroup? = null, - - @Enumerated(EnumType.STRING) - @ElementCollection(fetch = FetchType.EAGER) - @Fetch(FetchMode.SUBSELECT) - @get:JsonIgnore - val permissions: MutableList = mutableListOf(), - - val lastLoginTime: LocalDateTime? = null -) : IModel { - @JsonProperty("permissions") - fun getFlattenedPermissions(): Iterable = getPermissions() -} - -/** DTO for creating employees. Allow a [password] a [groupId]. */ -data class EmployeeDto( - @field:NotNull(message = EMPLOYEE_ID_NULL_MESSAGE) - val id: Long, - - @field:NotBlank(message = EMPLOYEE_FIRST_NAME_EMPTY_MESSAGE) - val firstName: String, - - @field:NotBlank(message = EMPLOYEE_LAST_NAME_EMPTY_MESSAGE) - val lastName: String, - - @field:NotBlank(message = EMPLOYEE_PASSWORD_EMPTY_MESSAGE) - @field:Size(min = 8, message = EMPLOYEE_PASSWORD_TOO_SHORT_MESSAGE) - val password: String, - - @field:ManyToOne - @Fetch(FetchMode.SELECT) - var groupId: Long? = null, - - @Enumerated(EnumType.STRING) - @ElementCollection(fetch = FetchType.EAGER) - val permissions: MutableList = mutableListOf() -) - -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 -data class EmployeeGroup( - @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE) - override val id: Long? = null, - - @field:NotBlank(message = GROUP_NAME_NULL_MESSAGE) - @field:Size(min = 3) - @Column(unique = true) - val name: String = "", - - @field:Size(min = 1, message = GROUP_PERMISSIONS_EMPTY_MESSAGE) - @Enumerated(EnumType.STRING) - @ElementCollection(fetch = FetchType.EAGER) - val permissions: MutableList = mutableListOf(), - - @OneToMany - @JsonIgnore - val employees: MutableList = mutableListOf() -) : IModel { - fun getEmployeeCount() = employees.size -} - - -data class EmployeeLoginRequest(val id: Long, val password: String) - - -enum class EmployeePermission(val impliedPermissions: List = listOf()) { - // View - VIEW_EMPLOYEE, - VIEW_EMPLOYEE_GROUP, - VIEW(listOf( - - )), - - // Edit - EDIT_EMPLOYEE(listOf(VIEW_EMPLOYEE)), - EDIT_EMPLOYEE_PASSWORD(listOf(EDIT_EMPLOYEE)), - EDIT_EMPLOYEE_GROUP(listOf(VIEW_EMPLOYEE_GROUP)), - EDIT(listOf( - VIEW - )), - - // Remove - REMOVE_EMPLOYEE(listOf(EDIT_EMPLOYEE)), - REMOVE_EMPLOYEE_GROUP(listOf(EDIT_EMPLOYEE_GROUP)), - REMOVE(listOf( - EDIT - )), - - // Others - SET_BROWSER_DEFAULT_GROUP(listOf( - VIEW_EMPLOYEE_GROUP - )), - - ADMIN(listOf( - REMOVE, - SET_BROWSER_DEFAULT_GROUP, - - // Admin only permissions - REMOVE_EMPLOYEE, - EDIT_EMPLOYEE_PASSWORD, - REMOVE_EMPLOYEE_GROUP, - )); - - operator fun contains(permission: EmployeePermission): Boolean { - return permission == this || impliedPermissions.any { permission in it } - } -} - -/** Gets [GrantedAuthority]s of the given [Employee]. */ -fun Employee.getAuthorities(): MutableCollection { - return getPermissions().map { it.toAuthority() }.toMutableSet() -} - -/** Gets [EmployeePermission]s of the given [Employee]. */ -fun Employee.getPermissions(): Iterable { - val grantedPermissions: MutableSet = mutableSetOf() - if (group != null) grantedPermissions.addAll(group!!.permissions.flatMap { it.flat() }) - grantedPermissions.addAll(permissions.flatMap { it.flat() }) - return grantedPermissions -} - -private fun EmployeePermission.flat(): Iterable { - return mutableSetOf(this).apply { - impliedPermissions.forEach { - addAll(it.flat()) - } - } -} - -/** Converts the given [EmployeePermission] to a [GrantedAuthority]. */ -private fun EmployeePermission.toAuthority(): GrantedAuthority { - return SimpleGrantedAuthority(name) -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/IModel.kt b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/IModel.kt deleted file mode 100644 index 03352f8..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/IModel.kt +++ /dev/null @@ -1,5 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model - -interface IModel { - val id: Long? -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Material.kt b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Material.kt deleted file mode 100644 index 78f8178..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Material.kt +++ /dev/null @@ -1,26 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model - -import org.springframework.lang.Nullable -import javax.persistence.* -import javax.validation.constraints.NotEmpty -import javax.validation.constraints.NotNull - -@Entity -data class Material( - @Nullable @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) override val id: Long?, - @NotNull @NotEmpty @Column(unique = true) var name: String?, - @NotNull var inventoryQuantity: Float, - @NotNull val isMixType: Boolean, - @NotNull @ManyToOne var materialType: MaterialType? -) : IModel { - constructor(name: String, inventoryQuantity: Float, isMixType: Boolean, materialType: MaterialType) : this(null, name, inventoryQuantity, isMixType, materialType) - constructor() : this(-1L, "", 0f, false, null) - - override fun equals(other: Any?): Boolean { - return other is Material && name == other.name - } - - override fun hashCode(): Int { - return name.hashCode() - } -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MaterialType.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MaterialType.java deleted file mode 100644 index a7d6a92..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MaterialType.java +++ /dev/null @@ -1,52 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model; - -import lombok.*; -import org.hibernate.annotations.ColumnDefault; - -import javax.persistence.*; -import javax.validation.constraints.NotNull; -import java.util.List; -import java.util.Objects; - -@Entity -@Data -@NoArgsConstructor -@RequiredArgsConstructor -@AllArgsConstructor -public class MaterialType implements IModel { - - public static final String IDENTIFIER_PREFIX_NAME = "prefix"; - - @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE) - private Long id; - - @NonNull - @NotNull - @Column(unique = true) - private String name; - - @NonNull - @NotNull - @Column(unique = true) - private String prefix; - - @NonNull - @NotNull - @ColumnDefault("false") - private boolean usePercentages; - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - MaterialType that = (MaterialType) o; - return name.equals(that.name) && - prefix.equals(that.prefix); - } - - @Override - public int hashCode() { - return Objects.hash(name, prefix); - } -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/config/MaterialTypeProperties.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/config/MaterialTypeProperties.java deleted file mode 100644 index 9cbbae8..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/config/MaterialTypeProperties.java +++ /dev/null @@ -1,21 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model.config; - -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import lombok.Getter; -import lombok.Setter; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -import java.util.List; - -@Component -@ConfigurationProperties(prefix = "entities.material-types") -@Getter -@Setter -public class MaterialTypeProperties { - - private List defaults; - - private String baseName; - -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/Service.kt b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/Service.kt deleted file mode 100644 index 54b096d..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/Service.kt +++ /dev/null @@ -1,79 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services - -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundRestException -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException -import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel -import org.springframework.data.jpa.repository.JpaRepository -import org.springframework.data.repository.findByIdOrNull - -/** A service implementing the basics CRUD operations. */ -interface IGenericService { - /** Gets all entities. */ - fun getAll(): Collection - - /** Saves a given [entity]. */ - fun save(entity: E): E - - /** Saves all given [entities]. */ - fun saveAll(entities: Iterable): Collection - - /** Updates a given [entity]. */ - fun update(entity: E): E - - /** Deletes a given [entity]. */ - fun delete(entity: E) - - /** Deletes all give [entities]. */ - fun deleteAll(entities: Iterable) -} - -/** A service for entities implementing the [IModel] interface. This service implements CRUD operations for [Long] identifiers. */ -interface IGenericModelService : IGenericService { - /** Checks if an entity with the given [id] exists. */ - fun existsById(id: Long): Boolean - - /** Gets the entity with the given [id]. */ - fun getById(id: Long): E - - /** Deletes the entity with the given [id]. */ - fun deleteById(id: Long) -} - -abstract class AbstractService>(val repository: R, val type: Class) : IGenericService { - override fun getAll(): Collection = repository.findAll() - - override fun save(entity: E): E = repository.save(entity) - - override fun saveAll(entities: Iterable): Collection = entities.map(this::save) - - override fun update(entity: E): E = repository.save(entity) - - override fun delete(entity: E) = repository.delete(entity) - - override fun deleteAll(entities: Iterable) = entities.forEach(this::delete) -} - -abstract class AbstractModelService>(repository: R, type: Class) : AbstractService(repository, type), IGenericModelService { - override fun existsById(id: Long): Boolean = repository.existsById(id) - - override fun getById(id: Long): E = repository.findByIdOrNull(id) - ?: throw EntityNotFoundException(type, ModelException.IdentifierType.ID, id) - - override fun save(entity: E): E { - with(entity.id) { - if (this != null && existsById(this)) - throw EntityNotFoundRestException(this) - } - - return super.save(entity) - } - - override fun deleteById(id: Long) = delete(getById(id)) -} - -/** Transforms the given object to JSON. **/ -fun Any.asJson(): String { - return jacksonObjectMapper().writeValueAsString(this) -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialService.java deleted file mode 100644 index 24681f4..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialService.java +++ /dev/null @@ -1,140 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.model; - -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import dev.fyloz.trial.colorrecipesexplorer.core.services.AbstractJavaService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.files.SimdutService; -import dev.fyloz.trial.colorrecipesexplorer.dao.MaterialRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - -import javax.validation.constraints.NotNull; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -@Service -public class MaterialService extends AbstractJavaService { - - private MixQuantityService mixQuantityService; - private SimdutService simdutService; - - public MaterialService() { - super(Material.class); - } - - @Autowired - public void setMaterialDao(MaterialRepository materialRepository) { - this.dao = materialRepository; - } - - @Autowired - public void setMixQuantityService(MixQuantityService mixQuantityService) { - this.mixQuantityService = mixQuantityService; - } - - @Autowired - public void setSimdutService(SimdutService simdutService) { - this.simdutService = simdutService; - } - - /** - * Vérifie si un produit correspondant à un nom existe. - * - * @param name Le nom du produit - * @return Si un produit correspondant au nom existe - */ - public boolean existsByName(String name) { - return dao.existsByName(name); - } - - /** - * 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 dao.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 - */ - public List getAllNotMixType() { - return getAll() - .stream() - .filter(m -> !m.isMixType()) - .collect(Collectors.toList()); - } - - /** - * Récupère le produit correspondant à un nom. - * - * @param name Le nom du produit à récupérer - * @return Le produit correspondant au nom - */ - public Material getByName(String name) { - Optional found = dao.findByName(name); - if (found.isEmpty()) throw new EntityNotFoundException(type, ModelException.IdentifierType.NAME, name); - - return found.get(); - } - - public Material save(@NotNull Material material, MultipartFile file) { - if (existsByName(material.getName())) - throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.NAME, material.getName()); - - Material saved = save(material); - - if (!file.isEmpty()) simdutService.write(saved, file); - - return saved; - } - - @Override - public Material update(Material material) { - Optional materialByName = dao.findByName(material.getName()); - if (materialByName.isPresent() && material.getId() != materialByName.get().getId()) - throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.NAME, material.getName()); - - return super.update(material); - } - - public Material update(Material material, MultipartFile simdut) { - simdutService.update(simdut, material); - - return update(material); - } - - @Override - public void delete(Material material) { - simdutService.delete(material); - - super.delete(material); - } - - @Deprecated(since = "1.3.0", forRemoval = true) - public void deleteIfNotLinked(Material material) { - if (!isLinkedToMixes(material)) { - delete(material); - } - } - -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/FileUtils.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/FileUtils.java deleted file mode 100644 index dda22ef..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/FileUtils.java +++ /dev/null @@ -1,23 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.utils; - -import org.springframework.core.io.ResourceLoader; -import org.springframework.util.FileCopyUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - -@Deprecated(since = "1.3.0", forRemoval = true) -public class FileUtils { - - public static String readClasspathFile(ResourceLoader loader, String path) { - try (InputStream stream = loader.getResource(path).getInputStream()) { - byte[] data = FileCopyUtils.copyToByteArray(stream); - return new String(data, StandardCharsets.UTF_8); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MaterialRepository.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MaterialRepository.java deleted file mode 100644 index 5756412..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MaterialRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.dao; - -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; - -@Repository -public interface MaterialRepository extends JpaRepository { - - boolean existsByName(String name); - - boolean existsByMaterialType(MaterialType materialType); - - Optional findByName(String name); - - List findAllByMaterialType(MaterialType materialType); - -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MaterialTypeRepository.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MaterialTypeRepository.java deleted file mode 100644 index 2463e08..0000000 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MaterialTypeRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.dao; - -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.Optional; - -public interface MaterialTypeRepository extends JpaRepository { - - boolean existsByName(String name); - - boolean existsByPrefix(String prefix); - - Optional findByPrefix(String prefix); - - Optional findByName(String name); - -} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/CannotDeleteDefaultMaterialTypeException.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/CannotDeleteDefaultMaterialTypeException.java similarity index 68% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/CannotDeleteDefaultMaterialTypeException.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/CannotDeleteDefaultMaterialTypeException.java index 7159817..2087581 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/CannotDeleteDefaultMaterialTypeException.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/CannotDeleteDefaultMaterialTypeException.java @@ -1,6 +1,6 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.exception; +package dev.fyloz.trial.colorrecipesexplorer.exception; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType; import lombok.Getter; @Getter diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/CannotEditDefaultMaterialTypeException.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/CannotEditDefaultMaterialTypeException.java similarity index 67% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/CannotEditDefaultMaterialTypeException.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/CannotEditDefaultMaterialTypeException.java index 8eb9404..787fac3 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/CannotEditDefaultMaterialTypeException.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/CannotEditDefaultMaterialTypeException.java @@ -1,6 +1,6 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.exception; +package dev.fyloz.trial.colorrecipesexplorer.exception; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MaterialTypeEditorDto; +import dev.fyloz.trial.colorrecipesexplorer.model.dto.MaterialTypeEditorDto; import lombok.Getter; @Getter diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/RestException.kt b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/RestException.kt similarity index 93% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/RestException.kt rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/RestException.kt index 2d53f98..1679f96 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/RestException.kt +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/RestException.kt @@ -1,7 +1,7 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.exception +package dev.fyloz.trial.colorrecipesexplorer.exception import com.fasterxml.jackson.annotation.JsonProperty -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.* +import dev.fyloz.trial.colorrecipesexplorer.exception.model.* import org.springframework.context.annotation.Profile import org.springframework.http.HttpHeaders import org.springframework.http.HttpStatus @@ -39,7 +39,7 @@ class RestResponseEntityExceptionHandler : ResponseEntityExceptionHandler() { val errors = hashMapOf() ex.bindingResult.allErrors.forEach { val fieldName = (it as FieldError).field - val errorMessage = it.defaultMessage + val errorMessage = it.defaultMessage!! errors[fieldName] = errorMessage } return ResponseEntity(errors, headers, status) diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/SimdutException.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/SimdutException.java similarity index 58% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/SimdutException.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/SimdutException.java index 3551703..ab6ed8b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/SimdutException.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/SimdutException.java @@ -1,6 +1,6 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.exception; +package dev.fyloz.trial.colorrecipesexplorer.exception; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; +import dev.fyloz.trial.colorrecipesexplorer.model.Material; public class SimdutException extends RuntimeException { diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/TooLowQuantityException.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/TooLowQuantityException.java similarity index 82% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/TooLowQuantityException.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/TooLowQuantityException.java index ab94cd9..6b96062 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/TooLowQuantityException.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/TooLowQuantityException.java @@ -1,6 +1,6 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.exception; +package dev.fyloz.trial.colorrecipesexplorer.exception; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; +import dev.fyloz.trial.colorrecipesexplorer.model.Material; import lombok.Getter; @Getter diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityAlreadyExistsException.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityAlreadyExistsException.java similarity index 90% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityAlreadyExistsException.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityAlreadyExistsException.java index 5810205..3b1088a 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityAlreadyExistsException.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityAlreadyExistsException.java @@ -1,6 +1,6 @@ -//package dev.fyloz.trial.colorrecipesexplorer.core.exception.model; +//package dev.fyloz.trial.colorrecipesexplorer.exception.model; // -//import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel; +//import dev.fyloz.trial.colorrecipesexplorer.model.IModel; //import lombok.Getter; //import lombok.NonNull; //import org.springframework.http.HttpStatus; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityAlreadyExistsException.kt b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityAlreadyExistsException.kt similarity index 52% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityAlreadyExistsException.kt rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityAlreadyExistsException.kt index 0ddac37..042a9e0 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityAlreadyExistsException.kt +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityAlreadyExistsException.kt @@ -1,12 +1,12 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.exception.model +package dev.fyloz.trial.colorrecipesexplorer.exception.model -import dev.fyloz.trial.colorrecipesexplorer.core.exception.RestException -import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel +import dev.fyloz.trial.colorrecipesexplorer.exception.RestException +import dev.fyloz.trial.colorrecipesexplorer.model.Model import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.ResponseStatus -class EntityAlreadyExistsException(modelType: Class, val identifierType: IdentifierType, val identifierName: String?, val requestedId: Any) : ModelException(modelType) { - constructor(modelType: Class, identifierType: IdentifierType, requestedId: Any) : this(modelType, identifierType, identifierType.name, requestedId) +class EntityAlreadyExistsException(modelType: Class, val identifierType: IdentifierType, val identifierName: String?, val requestedId: Any) : ModelException(modelType) { + constructor(modelType: Class, identifierType: IdentifierType, requestedId: Any) : this(modelType, identifierType, identifierType.name, requestedId) constructor(exception: EntityAlreadyExistsException) : this(exception.type, exception.identifierType, exception.identifierName, exception.requestedId) } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityLinkedException.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityLinkedException.java similarity index 53% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityLinkedException.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityLinkedException.java index b6c1f98..bb44bff 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityLinkedException.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityLinkedException.java @@ -1,13 +1,13 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.exception.model; +package dev.fyloz.trial.colorrecipesexplorer.exception.model; -import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel; +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 type) { + public EntityLinkedException(Class type) { super(type); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityNotFoundException.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityNotFoundException.java similarity index 89% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityNotFoundException.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityNotFoundException.java index 6308de8..5dac894 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityNotFoundException.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityNotFoundException.java @@ -1,6 +1,6 @@ -//package dev.fyloz.trial.colorrecipesexplorer.core.exception.model; +//package dev.fyloz.trial.colorrecipesexplorer.exception.model; // -//import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel; +//import dev.fyloz.trial.colorrecipesexplorer.model.IModel; //import lombok.Getter; // ///** diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityNotFoundException.kt b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityNotFoundException.kt new file mode 100644 index 0000000..fe499fd --- /dev/null +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/EntityNotFoundException.kt @@ -0,0 +1,19 @@ +package dev.fyloz.trial.colorrecipesexplorer.exception.model + +import dev.fyloz.trial.colorrecipesexplorer.exception.RestException +import dev.fyloz.trial.colorrecipesexplorer.model.Model +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.ResponseStatus + +class EntityNotFoundException(modelType: Class, val identifierType: IdentifierType, val identifierName: String, val requestedId: Any) : ModelException(modelType) { + constructor(modelType: Class, identifierType: IdentifierType, requestedId: Any) : this(modelType, identifierType, identifierType.name, requestedId) +} + +@ResponseStatus(HttpStatus.NOT_FOUND) +class EntityNotFoundRestException(val value: Any) : RestException(HttpStatus.NOT_FOUND) { + override val exceptionMessage: String = "An entity could not be found with the given identifier" + + override fun buildBody(): RestExceptionBody = object : RestExceptionBody() { + val id = value + } +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/ModelException.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/ModelException.java similarity index 66% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/ModelException.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/ModelException.java index 0e6f431..f259cfb 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/ModelException.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/ModelException.java @@ -1,6 +1,6 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.exception.model; +package dev.fyloz.trial.colorrecipesexplorer.exception.model; -import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel; +import dev.fyloz.trial.colorrecipesexplorer.model.Model; /** * Représente une exception qui sera déclenchée lors des opérations sur le modèle. @@ -10,13 +10,13 @@ public class ModelException extends RuntimeException { /** * Le type de modèle qui est sujet à l'exception */ - protected Class type; + protected Class type; - public ModelException(Class type) { + public ModelException(Class type) { this.type = type; } - public Class getType() { + public Class getType() { return type; } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/NullIdentifierException.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/NullIdentifierException.java similarity index 57% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/NullIdentifierException.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/NullIdentifierException.java index ede0a92..e6157cf 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/NullIdentifierException.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/exception/model/NullIdentifierException.java @@ -1,10 +1,10 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.exception.model; +package dev.fyloz.trial.colorrecipesexplorer.exception.model; -import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel; +import dev.fyloz.trial.colorrecipesexplorer.model.Model; public class NullIdentifierException extends ModelException { - public NullIdentifierException(Class type) { + public NullIdentifierException(Class type) { super(type); } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Company.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/Company.java similarity index 85% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Company.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/Company.java index 4fb3313..591230f 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Company.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/Company.java @@ -1,11 +1,11 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model; +package dev.fyloz.trial.colorrecipesexplorer.model; import lombok.*; import org.hibernate.validator.constraints.Length; +import org.jetbrains.annotations.Nullable; import javax.persistence.*; import javax.validation.constraints.NotNull; -import java.io.Serializable; import java.util.Objects; @Entity @@ -13,7 +13,7 @@ import java.util.Objects; @NoArgsConstructor @RequiredArgsConstructor @AllArgsConstructor -public class Company implements IModel { +public class Company implements Model { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Mix.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/Mix.java similarity index 88% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Mix.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/Mix.java index 62713b1..9a9eff5 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Mix.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/Mix.java @@ -1,6 +1,7 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model; +package dev.fyloz.trial.colorrecipesexplorer.model; import lombok.*; +import org.jetbrains.annotations.Nullable; import javax.persistence.*; import javax.validation.constraints.NotNull; @@ -11,7 +12,8 @@ import java.util.Objects; @Data @RequiredArgsConstructor @NoArgsConstructor -public class Mix implements IModel { +@AllArgsConstructor +public class Mix implements Model { public static final String IDENTIFIER_MIX_TYPE_NAME = "mixType"; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MixQuantity.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/MixQuantity.java similarity index 86% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MixQuantity.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/MixQuantity.java index b3a06fa..e3f5af1 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MixQuantity.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/MixQuantity.java @@ -1,7 +1,8 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model; +package dev.fyloz.trial.colorrecipesexplorer.model; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.*; +import org.jetbrains.annotations.Nullable; import javax.persistence.*; import javax.validation.constraints.NotNull; @@ -11,7 +12,8 @@ import java.util.Objects; @Data @RequiredArgsConstructor @NoArgsConstructor -public class MixQuantity implements IModel { +@AllArgsConstructor +public class MixQuantity implements Model { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MixType.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/MixType.java similarity index 88% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MixType.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/MixType.java index 3de3e44..30811e0 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MixType.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/MixType.java @@ -1,6 +1,7 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model; +package dev.fyloz.trial.colorrecipesexplorer.model; import lombok.*; +import org.jetbrains.annotations.Nullable; import javax.persistence.*; import javax.validation.constraints.NotNull; @@ -11,7 +12,7 @@ import java.util.Objects; @NoArgsConstructor @RequiredArgsConstructor @AllArgsConstructor -public class MixType implements IModel { +public class MixType implements Model { public static final String IDENTIFIER_MATERIAL_NAME = "material"; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Recipe.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/Recipe.java similarity index 95% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Recipe.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/Recipe.java index 4972215..ae99a9f 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Recipe.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/Recipe.java @@ -1,8 +1,9 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model; +package dev.fyloz.trial.colorrecipesexplorer.model; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.*; import org.hibernate.validator.constraints.Length; +import org.jetbrains.annotations.Nullable; import javax.persistence.*; import javax.validation.constraints.NotNull; @@ -13,7 +14,7 @@ import java.util.stream.Collectors; @Data @RequiredArgsConstructor @NoArgsConstructor -public class Recipe implements IModel { +public class Recipe implements Model { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/RecipeStep.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/RecipeStep.java similarity index 84% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/RecipeStep.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/RecipeStep.java index dfbf17b..a88c8c3 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/RecipeStep.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/RecipeStep.java @@ -1,18 +1,19 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model; +package dev.fyloz.trial.colorrecipesexplorer.model; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.*; +import org.jetbrains.annotations.Nullable; import javax.persistence.*; import javax.validation.constraints.NotNull; -import java.io.Serializable; import java.util.Objects; @Entity @Data @RequiredArgsConstructor @NoArgsConstructor -public class RecipeStep implements IModel { +@AllArgsConstructor +public class RecipeStep implements Model { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/InventoryDto.kt b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/InventoryDto.kt similarity index 62% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/InventoryDto.kt rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/InventoryDto.kt index 7e90017..9b12869 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/InventoryDto.kt +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/InventoryDto.kt @@ -1,3 +1,3 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model.dto +package dev.fyloz.trial.colorrecipesexplorer.model.dto data class InventoryDto(val mixId: Long, val materialIds: List, val quantities: List) diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/MaterialTypeEditorDto.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/MaterialTypeEditorDto.java similarity index 80% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/MaterialTypeEditorDto.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/MaterialTypeEditorDto.java index 02978bd..4456b23 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/MaterialTypeEditorDto.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/MaterialTypeEditorDto.java @@ -1,6 +1,6 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model.dto; +package dev.fyloz.trial.colorrecipesexplorer.model.dto; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -28,15 +28,15 @@ public class MaterialTypeEditorDto { this.name = materialType.getName(); this.oldPrefix = materialType.getPrefix(); this.prefix = materialType.getPrefix(); - this.usePercentages = materialType.isUsePercentages(); + this.usePercentages = materialType.getUsePercentages(); } public MaterialType getMaterialType() { - return new MaterialType(id, name, prefix, usePercentages); + return new MaterialType(id, name, prefix, usePercentages, false); } public MaterialType getOldMaterialType() { - return new MaterialType(id, oldName, oldPrefix, usePercentages); + return new MaterialType(id, oldName, oldPrefix, usePercentages, false); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/MixFormDto.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/MixFormDto.java similarity index 57% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/MixFormDto.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/MixFormDto.java index e9c1636..f8a6b4c 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/MixFormDto.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/MixFormDto.java @@ -1,8 +1,7 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model.dto; +package dev.fyloz.trial.colorrecipesexplorer.model.dto; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/RecipeEditorFormDto.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/RecipeEditorFormDto.java similarity index 81% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/RecipeEditorFormDto.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/RecipeEditorFormDto.java index 0d66a88..c2a9dd5 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/RecipeEditorFormDto.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/RecipeEditorFormDto.java @@ -1,7 +1,7 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model.dto; +package dev.fyloz.trial.colorrecipesexplorer.model.dto; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Company; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.model.Company; +import dev.fyloz.trial.colorrecipesexplorer.model.Recipe; import lombok.Data; import java.util.List; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/RecipeExplorerFormDto.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/RecipeExplorerFormDto.java similarity index 75% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/RecipeExplorerFormDto.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/RecipeExplorerFormDto.java index e2dbfdb..5168262 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/RecipeExplorerFormDto.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/model/dto/RecipeExplorerFormDto.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.model.dto; +package dev.fyloz.trial.colorrecipesexplorer.model.dto; import lombok.Data; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/CompanyRepository.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/CompanyRepository.java similarity index 67% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/CompanyRepository.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/CompanyRepository.java index 0c9c076..c418597 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/CompanyRepository.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/CompanyRepository.java @@ -1,6 +1,6 @@ -package dev.fyloz.trial.colorrecipesexplorer.dao; +package dev.fyloz.trial.colorrecipesexplorer.repository; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Company; +import dev.fyloz.trial.colorrecipesexplorer.model.Company; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MixQuantityRepository.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/MixQuantityRepository.java similarity index 65% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MixQuantityRepository.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/MixQuantityRepository.java index e4fc5bb..62df709 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MixQuantityRepository.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/MixQuantityRepository.java @@ -1,7 +1,7 @@ -package dev.fyloz.trial.colorrecipesexplorer.dao; +package dev.fyloz.trial.colorrecipesexplorer.repository; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixQuantity; +import dev.fyloz.trial.colorrecipesexplorer.model.Material; +import dev.fyloz.trial.colorrecipesexplorer.model.MixQuantity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MixRepository.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/MixRepository.java similarity index 60% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MixRepository.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/MixRepository.java index 2fe8942..6de331a 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MixRepository.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/MixRepository.java @@ -1,7 +1,7 @@ -package dev.fyloz.trial.colorrecipesexplorer.dao; +package dev.fyloz.trial.colorrecipesexplorer.repository; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Mix; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.model.Mix; +import dev.fyloz.trial.colorrecipesexplorer.model.Recipe; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MixTypeRepository.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/MixTypeRepository.java similarity index 67% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MixTypeRepository.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/MixTypeRepository.java index 52f8c45..e88ed7d 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/MixTypeRepository.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/MixTypeRepository.java @@ -1,7 +1,7 @@ -package dev.fyloz.trial.colorrecipesexplorer.dao; +package dev.fyloz.trial.colorrecipesexplorer.repository; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixType; +import dev.fyloz.trial.colorrecipesexplorer.model.Material; +import dev.fyloz.trial.colorrecipesexplorer.model.MixType; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/RecipeRepository.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/RecipeRepository.java similarity index 61% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/RecipeRepository.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/RecipeRepository.java index f0ad937..d9f2c2b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/RecipeRepository.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/RecipeRepository.java @@ -1,9 +1,8 @@ -package dev.fyloz.trial.colorrecipesexplorer.dao; +package dev.fyloz.trial.colorrecipesexplorer.repository; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Company; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.model.Company; +import dev.fyloz.trial.colorrecipesexplorer.model.Recipe; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import java.util.List; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/StepRepository.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/StepRepository.java similarity index 54% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/StepRepository.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/StepRepository.java index ccf70d1..31e10f8 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/StepRepository.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/repository/StepRepository.java @@ -1,7 +1,7 @@ -package dev.fyloz.trial.colorrecipesexplorer.dao; +package dev.fyloz.trial.colorrecipesexplorer.repository; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.model.RecipeStep; +import dev.fyloz.trial.colorrecipesexplorer.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.model.RecipeStep; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/AbstractJavaNamedService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/AbstractJavaNamedService.java new file mode 100644 index 0000000..182130d --- /dev/null +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/AbstractJavaNamedService.java @@ -0,0 +1,29 @@ +package dev.fyloz.trial.colorrecipesexplorer.service; + +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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> extends AbstractJavaService { + + public AbstractJavaNamedService(Class 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); + } + +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/AbstractJavaService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/AbstractJavaService.java similarity index 50% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/AbstractJavaService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/AbstractJavaService.java index d848dcf..8a8f1f6 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/AbstractJavaService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/AbstractJavaService.java @@ -1,13 +1,14 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services; +package dev.fyloz.trial.colorrecipesexplorer.service; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import dev.fyloz.trial.colorrecipesexplorer.core.Preferences; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.NullIdentifierException; -import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel; +import dev.fyloz.trial.colorrecipesexplorer.config.Preferences; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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; @@ -18,37 +19,72 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -public abstract class AbstractJavaService> implements IGenericJavaService { +public abstract class AbstractJavaService> implements IGenericJavaService { protected Logger logger = Preferences.logger; - protected R dao; + protected R repository; protected Class type; public AbstractJavaService(Class type) { this.type = type; } - @Override - public boolean exists(E entity) { - return entity != null && entity.getId() != null && existsById(entity.getId()); + public R getRepository() { + return repository; } @Override public boolean existsById(Long id) { - return dao.existsById(id); + return repository.existsById(id); + } + + /** + * Vérifie si une entité correspondant à un identifiant existe. + *

+ * 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. + *

+ * Méthode pour la compatibilité avec les repository Kotlin. + * + * @param entity L'entité nullable + * @return Un optional wrapper l'entité donnée + */ + protected Optional findOptional(@Nullable E entity) { + return Optional.ofNullable(entity); } @Override public E getById(Long id) { - Optional found = dao.findById(id); + Optional 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. + *

+ * 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 getAll() { - return dao.findAll(); + return repository.findAll(); } @Override @@ -56,7 +92,7 @@ public abstract class AbstractJavaService + * 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 entities) { - dao.deleteAll(entities); - } - - /** - * Vérifie si une entité est valide pour la création dans la base de données. - * - * @param entity L'entité à vérifier. - * @return Si l'entité est valide pour la création. - */ - @Deprecated(since = "1.3.0", forRemoval = true) - public boolean isValidForCreation(E entity) { - return entity != null && !existsById(entity.getId()); - } - - /** - * Vérifie si une entité est valide pour la création dans la base de données. - * - * @param entity L'entité à vérifier. - * @return Si l'entité est valide pour l'édition. - */ - @Deprecated(since = "1.3.0", forRemoval = true) - public boolean isValidForUpdate(@NotNull E entity) { - return entity.getId() != null && existsById(entity.getId()); + repository.deleteAll(entities); } /** diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/IGenericJavaService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/IGenericJavaService.java similarity index 86% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/IGenericJavaService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/IGenericJavaService.java index 72f9789..b0ae65b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/IGenericJavaService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/IGenericJavaService.java @@ -1,14 +1,11 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services; +package dev.fyloz.trial.colorrecipesexplorer.service; -import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel; +import dev.fyloz.trial.colorrecipesexplorer.model.Model; import java.util.Collection; import java.util.List; -public interface IGenericJavaService { - - @Deprecated(since = "1.3.0", forRemoval = true) - boolean exists(T entity); +public interface IGenericJavaService { /** * Vérifie si une entité correspondant à un identifiant existe. diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/PasswordService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/PasswordService.java similarity index 85% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/PasswordService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/PasswordService.java index 306b562..f48b689 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/PasswordService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/PasswordService.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services; +package dev.fyloz.trial.colorrecipesexplorer.service; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/FilesService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/FilesService.java similarity index 97% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/FilesService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/FilesService.java index b93d321..fb6134f 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/FilesService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/FilesService.java @@ -1,6 +1,6 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.files; +package dev.fyloz.trial.colorrecipesexplorer.service.files; -import dev.fyloz.trial.colorrecipesexplorer.core.Preferences; +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; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/ImagesService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/ImagesService.java similarity index 96% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/ImagesService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/ImagesService.java index 5f00b89..167ead5 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/ImagesService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/ImagesService.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.files; +package dev.fyloz.trial.colorrecipesexplorer.service.files; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/MarkdownFilesService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/MarkdownFilesService.java similarity index 93% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/MarkdownFilesService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/MarkdownFilesService.java index 1a9c580..714d404 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/MarkdownFilesService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/MarkdownFilesService.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.files; +package dev.fyloz.trial.colorrecipesexplorer.service.files; import org.commonmark.node.Node; import org.commonmark.parser.Parser; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/SimdutService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/SimdutService.java similarity index 89% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/SimdutService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/SimdutService.java index 9123e08..48df284 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/SimdutService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/SimdutService.java @@ -1,8 +1,8 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.files; +package dev.fyloz.trial.colorrecipesexplorer.service.files; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.SimdutException; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; +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; @@ -16,7 +16,7 @@ public class SimdutService { private static final String SIMDUT_DIRECTORY = "simdut"; private FilesService filesService; - private MaterialService materialService; + private MaterialJavaService materialService; @Autowired public SimdutService(FilesService filesService) { @@ -25,7 +25,7 @@ public class SimdutService { @Autowired @Lazy - public void setMaterialService(MaterialService materialService) { + public void setMaterialService(MaterialJavaService materialService) { this.materialService = materialService; } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/TouchUpKitService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/TouchUpKitService.java similarity index 90% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/TouchUpKitService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/TouchUpKitService.java index d899171..580582d 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/TouchUpKitService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/TouchUpKitService.java @@ -1,6 +1,6 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.files; +package dev.fyloz.trial.colorrecipesexplorer.service.files; -import dev.fyloz.trial.colorrecipesexplorer.core.utils.PdfBuilder; +import dev.fyloz.trial.colorrecipesexplorer.utils.PdfBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Service; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/XlsService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/XlsService.java similarity index 89% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/XlsService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/XlsService.java index 3f1c455..df39c2c 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/XlsService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/files/XlsService.java @@ -1,8 +1,8 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.files; +package dev.fyloz.trial.colorrecipesexplorer.service.files; -import dev.fyloz.trial.colorrecipesexplorer.core.Preferences; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +import dev.fyloz.trial.colorrecipesexplorer.config.Preferences; +import dev.fyloz.trial.colorrecipesexplorer.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeService; import dev.fyloz.trial.colorrecipesexplorer.xlsx.XlsxExporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/CompanyService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/CompanyService.java similarity index 74% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/CompanyService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/CompanyService.java index 3891b75..9f01028 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/CompanyService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/CompanyService.java @@ -1,11 +1,11 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.model; +package dev.fyloz.trial.colorrecipesexplorer.service.model; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityLinkedException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Company; -import dev.fyloz.trial.colorrecipesexplorer.core.services.AbstractJavaService; -import dev.fyloz.trial.colorrecipesexplorer.dao.CompanyRepository; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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.service.AbstractJavaService; +import dev.fyloz.trial.colorrecipesexplorer.repository.CompanyRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -23,7 +23,7 @@ public class CompanyService extends AbstractJavaService { + + private MixQuantityService mixQuantityService; + private SimdutService simdutService; + + public MaterialJavaService() { + super(Material.class); + } + + @Autowired + public void setMaterialDao(MaterialRepository materialRepository) { + this.repository = materialRepository; + } + + @Autowired + public void setMixQuantityService(MixQuantityService 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 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 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); + } + +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialTypeService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/MaterialTypeJavaService.java similarity index 66% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialTypeService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/MaterialTypeJavaService.java index 7d8e18c..2477edc 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialTypeService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/MaterialTypeJavaService.java @@ -1,14 +1,15 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.model; +package dev.fyloz.trial.colorrecipesexplorer.service.model; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.CannotDeleteDefaultMaterialTypeException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.CannotEditDefaultMaterialTypeException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MaterialTypeEditorDto; -import dev.fyloz.trial.colorrecipesexplorer.core.services.AbstractJavaService; -import dev.fyloz.trial.colorrecipesexplorer.dao.MaterialTypeRepository; +import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteDefaultMaterialTypeException; +import dev.fyloz.trial.colorrecipesexplorer.exception.CannotEditDefaultMaterialTypeException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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; @@ -19,23 +20,23 @@ import java.util.Optional; import java.util.stream.Collectors; @Service -public class MaterialTypeService extends AbstractJavaService { +public class MaterialTypeJavaService extends AbstractJavaService { - private MaterialService materialService; + private MaterialJavaService materialService; private List defaultMaterialTypes = new LinkedList<>(); - public MaterialTypeService() { + public MaterialTypeJavaService() { super(MaterialType.class); } @Autowired public void setMaterialTypeDao(MaterialTypeRepository materialTypeRepository) { - this.dao = materialTypeRepository; + this.repository = materialTypeRepository; } @Autowired - public void setMaterialService(MaterialService materialService) { + public void setMaterialService(MaterialJavaService materialService) { this.materialService = materialService; } @@ -69,7 +70,7 @@ public class MaterialTypeService extends AbstractJavaService found = dao.findByName(name); + Optional found = findOptional(repository.findByName(name)); if (found.isEmpty()) throw new EntityNotFoundException(type, ModelException.IdentifierType.NAME, name); @@ -122,7 +123,7 @@ public class MaterialTypeService extends AbstractJavaService { - private MaterialService materialService; + private MaterialJavaService materialService; private MixQuantityService mixQuantityService; private MixTypeService mixTypeService; @@ -31,11 +31,11 @@ public class MixService extends AbstractJavaService { @Autowired public void setMixDao(MixRepository mixRepository) { - this.dao = mixRepository; + this.repository = mixRepository; } @Autowired - public void setMaterialService(MaterialService materialService) { + public void setMaterialService(MaterialJavaService materialService) { this.materialService = materialService; } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixTypeService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/MixTypeService.java similarity index 71% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixTypeService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/MixTypeService.java index eae92d0..ab9cf12 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixTypeService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/MixTypeService.java @@ -1,13 +1,13 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.model; +package dev.fyloz.trial.colorrecipesexplorer.service.model; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixType; -import dev.fyloz.trial.colorrecipesexplorer.core.services.AbstractJavaService; -import dev.fyloz.trial.colorrecipesexplorer.dao.MixTypeRepository; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException; +import dev.fyloz.trial.colorrecipesexplorer.model.Material; +import dev.fyloz.trial.colorrecipesexplorer.model.MixType; +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType; +import dev.fyloz.trial.colorrecipesexplorer.service.AbstractJavaService; +import dev.fyloz.trial.colorrecipesexplorer.repository.MixTypeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -17,7 +17,7 @@ import java.util.Optional; @Service public class MixTypeService extends AbstractJavaService { - private MaterialService materialService; + private MaterialJavaService materialService; public MixTypeService() { super(MixType.class); @@ -25,11 +25,11 @@ public class MixTypeService extends AbstractJavaService found = dao.findByName(name); + Optional found = repository.findByName(name); if (found.isEmpty()) throw new EntityNotFoundException(type, ModelException.IdentifierType.NAME, name); return found.get(); @@ -63,7 +63,7 @@ public class MixTypeService extends AbstractJavaService found = dao.findByMaterial(material); + Optional found = repository.findByMaterial(material); if (found.isEmpty()) throw new EntityNotFoundException(type, ModelException.IdentifierType.OTHER, MixType.IDENTIFIER_MATERIAL_NAME, material); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/RecipeService.java similarity index 88% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/RecipeService.java index 5f659b5..4edb11b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/RecipeService.java @@ -1,13 +1,13 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.model; +package dev.fyloz.trial.colorrecipesexplorer.service.model; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Company; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Mix; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.RecipeEditorFormDto; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.RecipeExplorerFormDto; -import dev.fyloz.trial.colorrecipesexplorer.core.services.AbstractJavaService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.files.ImagesService; -import dev.fyloz.trial.colorrecipesexplorer.dao.RecipeRepository; +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.service.AbstractJavaService; +import dev.fyloz.trial.colorrecipesexplorer.service.files.ImagesService; +import dev.fyloz.trial.colorrecipesexplorer.repository.RecipeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -30,7 +30,7 @@ public class RecipeService extends AbstractJavaService @Autowired public void setRecipeDao(RecipeRepository recipeRepository) { - this.dao = recipeRepository; + this.repository = recipeRepository; } @Autowired @@ -60,7 +60,7 @@ public class RecipeService extends AbstractJavaService * @return S'il y a une recette liée à la compagnie */ public boolean existsByCompany(Company company) { - return dao.existsByCompany(company); + return repository.existsByCompany(company); } /** @@ -70,7 +70,7 @@ public class RecipeService extends AbstractJavaService * @return Toutes les recettes pour la compagnie */ public Collection getAllByCompany(Company company) { - return dao.findAllByCompany(company); + return repository.findAllByCompany(company); } /** diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/StepService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/StepService.java similarity index 75% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/StepService.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/StepService.java index 98675fc..995f77a 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/StepService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/service/model/StepService.java @@ -1,9 +1,9 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services.model; +package dev.fyloz.trial.colorrecipesexplorer.service.model; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.model.RecipeStep; -import dev.fyloz.trial.colorrecipesexplorer.core.services.AbstractJavaService; -import dev.fyloz.trial.colorrecipesexplorer.dao.StepRepository; +import dev.fyloz.trial.colorrecipesexplorer.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.model.RecipeStep; +import dev.fyloz.trial.colorrecipesexplorer.service.AbstractJavaService; +import dev.fyloz.trial.colorrecipesexplorer.repository.StepRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -20,7 +20,7 @@ public class StepService extends AbstractJavaService @Autowired public void setStepDao(StepRepository stepRepository) { - this.dao = stepRepository; + this.repository = stepRepository; } /** diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/ControllerUtils.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/utils/ControllerUtils.java similarity index 94% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/ControllerUtils.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/utils/ControllerUtils.java index cbb2289..c864f0d 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/ControllerUtils.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/utils/ControllerUtils.java @@ -1,6 +1,6 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.utils; +package dev.fyloz.trial.colorrecipesexplorer.utils; -import dev.fyloz.trial.colorrecipesexplorer.core.Preferences; +import dev.fyloz.trial.colorrecipesexplorer.config.Preferences; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/MixBuilder.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/utils/MixBuilder.java similarity index 85% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/MixBuilder.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/utils/MixBuilder.java index 2ad0b03..d03b678 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/MixBuilder.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/utils/MixBuilder.java @@ -1,17 +1,17 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.utils; +package dev.fyloz.trial.colorrecipesexplorer.utils; -import dev.fyloz.trial.colorrecipesexplorer.core.model.*; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MixFormDto; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MixTypeService; +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.MixTypeService; +import dev.fyloz.trial.colorrecipesexplorer.model.Material; import java.util.*; -import java.util.stream.Stream; public class MixBuilder { private MixTypeService mixTypeService; - private MaterialService materialService; + private MaterialJavaService materialService; private Long id; private Recipe recipe; @@ -21,7 +21,7 @@ public class MixBuilder { private Map quantities = new LinkedHashMap<>(); - public MixBuilder(MixTypeService mixTypeService, MaterialService materialService) { + public MixBuilder(MixTypeService mixTypeService, MaterialJavaService materialService) { this.mixTypeService = mixTypeService; this.materialService = materialService; } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/PdfBuilder.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/utils/PdfBuilder.java similarity index 98% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/PdfBuilder.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/utils/PdfBuilder.java index 8abb2f7..22c5e78 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/PdfBuilder.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/utils/PdfBuilder.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.utils; +package dev.fyloz.trial.colorrecipesexplorer.utils; import dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths; import lombok.AllArgsConstructor; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/CREErrorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/CREErrorController.java index 3fa1054..e56894b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/CREErrorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/CREErrorController.java @@ -1,7 +1,7 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; +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; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/Controllers.kt b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/Controllers.kt index 177b753..34654ea 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/Controllers.kt +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/Controllers.kt @@ -1,7 +1,7 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode -import dev.fyloz.trial.colorrecipesexplorer.core.utils.ControllerUtils +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 { diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/IndexController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/IndexController.java index c292916..a637574 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/IndexController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/IndexController.java @@ -1,9 +1,9 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.services.PasswordService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +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.RecipeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.http.MediaType; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/InventoryController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/InventoryController.java index c34e541..f4f9551 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/InventoryController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/InventoryController.java @@ -1,14 +1,14 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.TooLowQuantityException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.JSONResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.InventoryDto; -import dev.fyloz.trial.colorrecipesexplorer.core.services.InventoryService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService; +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; @@ -32,11 +32,11 @@ import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.USE_INVENTOR public class InventoryController { private InventoryService inventoryService; - private MaterialService materialService; - private MaterialTypeService materialTypeService; + private MaterialJavaService materialService; + private MaterialTypeJavaService materialTypeService; @Autowired - public InventoryController(InventoryService inventoryService, MaterialService materialService, MaterialTypeService materialTypeService) { + public InventoryController(InventoryService inventoryService, MaterialJavaService materialService, MaterialTypeJavaService materialTypeService) { this.inventoryService = inventoryService; this.materialService = materialService; this.materialTypeService = materialTypeService; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/OthersController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/OthersController.java index 3f6f00e..fc0b723 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/OthersController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/OthersController.java @@ -1,11 +1,11 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.services.files.MarkdownFilesService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MixService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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.MixService; +import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.http.HttpStatus; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/RecipeExplorerController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/RecipeExplorerController.java index 0e34fc7..e48ba27 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/RecipeExplorerController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/RecipeExplorerController.java @@ -1,13 +1,13 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.JSONResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.RecipeExplorerFormDto; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundException; +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.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.model.dto.RecipeExplorerFormDto; +import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.http.MediaType; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/CompanyCreatorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/CompanyCreatorController.java index 58ca2d3..f3d5784 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/CompanyCreatorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/CompanyCreatorController.java @@ -1,11 +1,11 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Company; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.CompanyService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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.Company; +import dev.fyloz.trial.colorrecipesexplorer.service.model.CompanyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.http.MediaType; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialCreatorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialCreatorController.java index e2d15d5..65c902a 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialCreatorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialCreatorController.java @@ -1,13 +1,13 @@ //package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators; // -//import dev.fyloz.trial.colorrecipesexplorer.core.exception.SimdutException; -//import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -//import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -//import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -//import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -//import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -//import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; -//import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService; +//import dev.fyloz.trial.colorrecipesexplorer.exception.SimdutException; +//import dev.fyloz.trial.colorrecipesexplorer.exception.model.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; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialCreatorController.kt b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialCreatorController.kt index 39f39be..ebc8a4b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialCreatorController.kt +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialCreatorController.kt @@ -1,11 +1,12 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators -import dev.fyloz.trial.colorrecipesexplorer.core.exception.SimdutException -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService +import dev.fyloz.trial.colorrecipesexplorer.exception.SimdutException +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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 @@ -21,7 +22,7 @@ import javax.validation.Valid @Controller @Profile("thymeleaf") -class MaterialCreatorController(val materialService: MaterialService, val materialTypeService: MaterialTypeService) { +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) { @@ -35,7 +36,7 @@ class MaterialCreatorController(val materialService: MaterialService, val materi fun createMaterial(@Valid material: Material, simdut: MultipartFile): ModelAndView { return getPage(modelAndView { try { - materialService.save(material, simdut) + 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) diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialTypeCreatorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialTypeCreatorController.java index b738721..6931697 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialTypeCreatorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MaterialTypeCreatorController.java @@ -1,13 +1,13 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService; -import dev.fyloz.trial.colorrecipesexplorer.core.utils.ControllerUtils; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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; @@ -24,10 +24,10 @@ import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.INDEX; @Profile("thymeleaf") public class MaterialTypeCreatorController { - private MaterialTypeService materialTypeService; + private MaterialTypeJavaService materialTypeService; @Autowired - public MaterialTypeCreatorController(MaterialTypeService materialTypeService) { + public MaterialTypeCreatorController(MaterialTypeJavaService materialTypeService) { this.materialTypeService = materialTypeService; } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MixCreatorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MixCreatorController.java index 9a5948b..e86e9a4 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MixCreatorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/MixCreatorController.java @@ -1,16 +1,16 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Mix; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MixFormDto; -import dev.fyloz.trial.colorrecipesexplorer.core.services.ServiceKt; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.*; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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.Mix; +import dev.fyloz.trial.colorrecipesexplorer.model.MixType; +import dev.fyloz.trial.colorrecipesexplorer.model.Recipe; +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; @@ -31,11 +31,11 @@ public class MixCreatorController { private MixService mixService; private RecipeService recipeService; - private MaterialService materialService; - private MaterialTypeService materialTypeService; + private MaterialJavaService materialService; + private MaterialTypeJavaService materialTypeService; @Autowired - public MixCreatorController(MixService mixService, RecipeService recipeService, MaterialService materialService, MixTypeService mixTypeService, MaterialTypeService materialTypeService) { + public MixCreatorController(MixService mixService, RecipeService recipeService, MaterialJavaService materialService, MixTypeService mixTypeService, MaterialTypeJavaService materialTypeService) { this.mixService = mixService; this.recipeService = recipeService; this.materialService = materialService; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/RecipeCreatorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/RecipeCreatorController.java index a28f7a2..d1116d6 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/RecipeCreatorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/creators/RecipeCreatorController.java @@ -1,11 +1,11 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.CompanyService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +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.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.service.model.CompanyService; +import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Controller; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MaterialEditorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MaterialEditorController.java index 23c5aef..79de636 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MaterialEditorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MaterialEditorController.java @@ -1,14 +1,15 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.editors; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.SimdutException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService; +import dev.fyloz.trial.colorrecipesexplorer.exception.SimdutException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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; @@ -25,11 +26,11 @@ import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Profile("thymeleaf") public class MaterialEditorController { - private MaterialService materialService; - private MaterialTypeService materialTypeService; + private MaterialJavaService materialService; + private MaterialTypeJavaService materialTypeService; @Autowired - public MaterialEditorController(MaterialService materialService, MaterialTypeService materialTypeService) { + public MaterialEditorController(MaterialJavaService materialService, MaterialTypeJavaService materialTypeService) { this.materialService = materialService; this.materialTypeService = materialTypeService; } @@ -92,7 +93,7 @@ public class MaterialEditorController { try { Material material = materialService.getById(id); - materialService.update(material, simdut); + 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(), diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MaterialTypeEditorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MaterialTypeEditorController.java index 05f2d4c..9f3d59d 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MaterialTypeEditorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MaterialTypeEditorController.java @@ -1,15 +1,15 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.editors; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.CannotEditDefaultMaterialTypeException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MaterialTypeEditorDto; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService; +import dev.fyloz.trial.colorrecipesexplorer.exception.CannotEditDefaultMaterialTypeException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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; @@ -25,10 +25,10 @@ import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Profile("thymeleaf") public class MaterialTypeEditorController { - private MaterialTypeService materialTypeService; + private MaterialTypeJavaService materialTypeService; @Autowired - public MaterialTypeEditorController(MaterialTypeService materialTypeService) { + public MaterialTypeEditorController(MaterialTypeJavaService materialTypeService) { this.materialTypeService = materialTypeService; } @@ -68,7 +68,7 @@ public class MaterialTypeEditorController { } catch (EntityAlreadyExistsException ex) { if (ModelException.IdentifierType.NAME.equals(ex.getIdentifierType())) responseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_ALREADY_EXIST, materialTypeDto.getMaterialType().getName()); - else if (ex.getIdentifierName().equals(MaterialType.IDENTIFIER_PREFIX_NAME)) + 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); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MixEditorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MixEditorController.java index 8dbea10..1517d4b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MixEditorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/MixEditorController.java @@ -1,16 +1,16 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.editors; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Mix; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MixFormDto; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MixService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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.Mix; +import dev.fyloz.trial.colorrecipesexplorer.model.MixType; +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.MixService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.http.MediaType; @@ -27,11 +27,11 @@ import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; public class MixEditorController { private MixService mixService; - private MaterialService materialService; - private MaterialTypeService materialTypeService; + private MaterialJavaService materialService; + private MaterialTypeJavaService materialTypeService; @Autowired - public MixEditorController(MixService mixService, MaterialService materialService, MaterialTypeService materialTypeService) { + public MixEditorController(MixService mixService, MaterialJavaService materialService, MaterialTypeJavaService materialTypeService) { this.mixService = mixService; this.materialService = materialService; this.materialTypeService = materialTypeService; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/RecipeEditorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/RecipeEditorController.java index ade9e61..452627f 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/RecipeEditorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/editors/RecipeEditorController.java @@ -1,13 +1,13 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.editors; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.RecipeEditorFormDto; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.CompanyService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.model.dto.RecipeEditorFormDto; +import dev.fyloz.trial.colorrecipesexplorer.service.model.CompanyService; +import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.http.MediaType; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/ImageFilesController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/ImageFilesController.java index c2e24e6..d51658b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/ImageFilesController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/ImageFilesController.java @@ -1,13 +1,13 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.files; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.JSONResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.services.files.ImagesService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundException; +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.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.service.files.ImagesService; +import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.http.HttpHeaders; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/SimdutFilesController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/SimdutFilesController.java index 227f40f..d79236b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/SimdutFilesController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/SimdutFilesController.java @@ -1,7 +1,7 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.files; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.services.files.SimdutService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/TouchUpKitController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/TouchUpKitController.java index a23e702..96175dc 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/TouchUpKitController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/TouchUpKitController.java @@ -1,9 +1,9 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.files; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.services.files.TouchUpKitService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +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.RecipeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.http.HttpStatus; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/XlsExporterController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/XlsExporterController.java index 5869d08..a420e4f 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/XlsExporterController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/files/XlsExporterController.java @@ -1,7 +1,7 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.files; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.services.files.XlsService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/CompanyRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/CompanyRemoverController.java index f139c6f..c7b0888 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/CompanyRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/CompanyRemoverController.java @@ -1,12 +1,12 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.removers; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityLinkedException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Company; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.CompanyService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityLinkedException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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.Company; +import dev.fyloz.trial.colorrecipesexplorer.service.model.CompanyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Controller; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MaterialRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MaterialRemoverController.java index 19951ed..e704505 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MaterialRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MaterialRemoverController.java @@ -1,12 +1,12 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.removers; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityLinkedException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityLinkedException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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; @@ -24,10 +24,10 @@ import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_MATE @Profile("thymeleaf") public class MaterialRemoverController { - private MaterialService materialService; + private MaterialJavaService materialService; @Autowired - public MaterialRemoverController(MaterialService materialService) { + public MaterialRemoverController(MaterialJavaService materialService) { this.materialService = materialService; } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MaterialTypeRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MaterialTypeRemoverController.java index ce1ff2c..990a3ac 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MaterialTypeRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MaterialTypeRemoverController.java @@ -1,13 +1,13 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.removers; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.CannotDeleteDefaultMaterialTypeException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityLinkedException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService; +import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteDefaultMaterialTypeException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityLinkedException; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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; @@ -23,11 +23,11 @@ import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_MATE @Profile("thymeleaf") public class MaterialTypeRemoverController { - private MaterialTypeService materialTypeService; + private MaterialTypeJavaService materialTypeService; @Autowired - public MaterialTypeRemoverController(MaterialTypeService materialTypeService) { + public MaterialTypeRemoverController(MaterialTypeJavaService materialTypeService) { this.materialTypeService = materialTypeService; } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MixRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MixRemoverController.java index 0a3a08b..3971032 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MixRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/MixRemoverController.java @@ -1,10 +1,10 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.removers; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Mix; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MixService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundException; +import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder; +import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode; +import dev.fyloz.trial.colorrecipesexplorer.model.Mix; +import dev.fyloz.trial.colorrecipesexplorer.service.model.MixService; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/RecipeRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/RecipeRemoverController.java index a8651f7..d282032 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/RecipeRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/thymeleaf/removers/RecipeRemoverController.java @@ -1,11 +1,11 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.removers; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; -import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +import dev.fyloz.trial.colorrecipesexplorer.exception.model.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.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeService; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/JSONResponseBuilder.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/JSONResponseBuilder.java similarity index 87% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/JSONResponseBuilder.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/JSONResponseBuilder.java index a833243..9ed2bd5 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/JSONResponseBuilder.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/JSONResponseBuilder.java @@ -1,6 +1,6 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.io.response; +package dev.fyloz.trial.colorrecipesexplorer.web.response; -import dev.fyloz.trial.colorrecipesexplorer.core.Preferences; +import dev.fyloz.trial.colorrecipesexplorer.config.Preferences; import org.springframework.context.i18n.LocaleContextHolder; import java.util.HashMap; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ModelResponseBuilder.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ModelResponseBuilder.java similarity index 96% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ModelResponseBuilder.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ModelResponseBuilder.java index 12ab1bc..cfcef7f 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ModelResponseBuilder.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ModelResponseBuilder.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.io.response; +package dev.fyloz.trial.colorrecipesexplorer.web.response; import org.springframework.web.servlet.ModelAndView; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseBuilder.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ResponseBuilder.java similarity index 94% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseBuilder.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ResponseBuilder.java index fe2fac6..1ce9970 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseBuilder.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ResponseBuilder.java @@ -1,10 +1,9 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.io.response; +package dev.fyloz.trial.colorrecipesexplorer.web.response; -import dev.fyloz.trial.colorrecipesexplorer.core.Preferences; -import dev.fyloz.trial.colorrecipesexplorer.core.utils.ControllerUtils; +import dev.fyloz.trial.colorrecipesexplorer.config.Preferences; +import dev.fyloz.trial.colorrecipesexplorer.utils.ControllerUtils; import org.springframework.lang.Nullable; -import javax.validation.constraints.NotNull; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseCode.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ResponseCode.java similarity index 97% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseCode.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ResponseCode.java index 1207786..8890ca6 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseCode.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ResponseCode.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.io.response; +package dev.fyloz.trial.colorrecipesexplorer.web.response; public enum ResponseCode { SUCCESS_USING_MATERIALS(1, ResponseCodeType.SUCCESS, 0), diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseDataType.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ResponseDataType.java similarity index 89% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseDataType.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ResponseDataType.java index 2ca43f1..290ece88 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseDataType.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/response/ResponseDataType.java @@ -1,7 +1,9 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.io.response; +package dev.fyloz.trial.colorrecipesexplorer.web.response; -import dev.fyloz.trial.colorrecipesexplorer.core.model.*; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MaterialTypeEditorDto; +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; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/xlsx/XlsxExporter.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/xlsx/XlsxExporter.java index 663430c..4929887 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/xlsx/XlsxExporter.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/xlsx/XlsxExporter.java @@ -1,10 +1,10 @@ package dev.fyloz.trial.colorrecipesexplorer.xlsx; -import dev.fyloz.trial.colorrecipesexplorer.core.Preferences; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Mix; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixQuantity; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.model.RecipeStep; +import dev.fyloz.trial.colorrecipesexplorer.config.Preferences; +import dev.fyloz.trial.colorrecipesexplorer.model.Mix; +import dev.fyloz.trial.colorrecipesexplorer.model.MixQuantity; +import dev.fyloz.trial.colorrecipesexplorer.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.model.RecipeStep; import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.Catalog; import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.Document; import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.Sheet; @@ -70,7 +70,7 @@ public class XlsxExporter { for (MixQuantity mixQuantity : mix.getMixQuantities()) { mixTable.setRowName(row, mixQuantity.getMaterial().getName()); mixTable.setContent(new Position(1, row + 1), mixQuantity.getQuantity()); - mixTable.setContent(new Position(3, row + 1), mixQuantity.getMaterial().getMaterialType().isUsePercentages() ? "%" : "mL"); + mixTable.setContent(new Position(3, row + 1), mixQuantity.getMaterial().getMaterialType().getUsePercentages() ? "%" : "mL"); row++; } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/xlsx/component/Document.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/xlsx/component/Document.java index e17cf40..1256648 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/xlsx/component/Document.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/xlsx/component/Document.java @@ -1,6 +1,6 @@ package dev.fyloz.trial.colorrecipesexplorer.xlsx.component; -import dev.fyloz.trial.colorrecipesexplorer.core.Preferences; +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; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplication.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplication.kt similarity index 52% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplication.kt rename to src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplication.kt index 1ab5b17..e43d339 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplication.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplication.kt @@ -1,15 +1,18 @@ package dev.fyloz.trial.colorrecipesexplorer -import dev.fyloz.trial.colorrecipesexplorer.core.model.config.CREProperties -import dev.fyloz.trial.colorrecipesexplorer.core.model.config.MaterialTypeProperties +import dev.fyloz.trial.colorrecipesexplorer.config.properties.CREProperties +import dev.fyloz.trial.colorrecipesexplorer.config.properties.MaterialTypeProperties +import dev.fyloz.trial.colorrecipesexplorer.repository.MaterialTypeRepository +import dev.fyloz.trial.colorrecipesexplorer.repository.NamedJpaRepository import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.boot.runApplication -import org.springframework.cache.annotation.EnableCaching +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.FilterType +import org.springframework.data.jpa.repository.config.EnableJpaRepositories @SpringBootApplication @EnableConfigurationProperties(MaterialTypeProperties::class, CREProperties::class) -@EnableCaching class ColorRecipesExplorerApplication fun main(args: Array) { diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/WebSecurityConfig.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/config/WebSecurityConfig.kt similarity index 94% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/WebSecurityConfig.kt rename to src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/config/WebSecurityConfig.kt index dfcd2d6..baf67e1 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/WebSecurityConfig.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/config/WebSecurityConfig.kt @@ -1,11 +1,11 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.configuration +package dev.fyloz.trial.colorrecipesexplorer.config import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import dev.fyloz.trial.colorrecipesexplorer.core.model.Employee -import dev.fyloz.trial.colorrecipesexplorer.core.model.EmployeeLoginRequest -import dev.fyloz.trial.colorrecipesexplorer.core.model.EmployeePermission -import dev.fyloz.trial.colorrecipesexplorer.core.services.EmployeeService -import dev.fyloz.trial.colorrecipesexplorer.core.services.EmployeeUserDetailsService +import dev.fyloz.trial.colorrecipesexplorer.model.Employee +import dev.fyloz.trial.colorrecipesexplorer.model.EmployeeLoginRequest +import dev.fyloz.trial.colorrecipesexplorer.model.EmployeePermission +import dev.fyloz.trial.colorrecipesexplorer.service.EmployeeServiceImpl +import dev.fyloz.trial.colorrecipesexplorer.service.EmployeeUserDetailsServiceImpl import io.jsonwebtoken.Jwts import io.jsonwebtoken.SignatureAlgorithm import org.slf4j.Logger @@ -57,10 +57,10 @@ class WebSecurityConfig( val securityConfigurationProperties: SecurityConfigurationProperties, val logger: Logger) : WebSecurityConfigurerAdapter() { @Autowired - private lateinit var userDetailsService: EmployeeUserDetailsService + private lateinit var userDetailsService: EmployeeUserDetailsServiceImpl @Autowired - private lateinit var employeeService: EmployeeService + private lateinit var employeeService: EmployeeServiceImpl override fun configure(authBuilder: AuthenticationManagerBuilder) { authBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()) @@ -108,7 +108,7 @@ class WebSecurityConfig( lastName = lastName, password = passwordEncoder().encode(credentials.password!!), isSystemUser = true, - permissions = permissions.toMutableList() + permissions = permissions.toMutableSet() )) } } @@ -173,7 +173,7 @@ val blacklistedJwtTokens = mutableListOf() class JwtAuthenticationFilter( val authManager: AuthenticationManager, - val employeeService: EmployeeService, + val employeeService: EmployeeServiceImpl, val securityConfigurationProperties: SecurityConfigurationProperties ) : UsernamePasswordAuthenticationFilter() { init { @@ -207,7 +207,7 @@ class JwtAuthenticationFilter( } class JwtAuthorizationFilter( - val userDetailsService: EmployeeUserDetailsService, + val userDetailsService: EmployeeUserDetailsServiceImpl, val securityConfigurationProperties: SecurityConfigurationProperties, authenticationManager: AuthenticationManager ) : BasicAuthenticationFilter(authenticationManager) { @@ -249,7 +249,6 @@ class SecurityConfigurationProperties { var jwtSecret: String? = null var jwtDuration: Long? = null var root: SystemUserCredentials? = null - var common: SystemUserCredentials? = null class SystemUserCredentials(var id: Long? = null, var password: String? = null) } diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/config/properties/MaterialTypeProperties.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/config/properties/MaterialTypeProperties.kt new file mode 100644 index 0000000..367532f --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/config/properties/MaterialTypeProperties.kt @@ -0,0 +1,25 @@ +package dev.fyloz.trial.colorrecipesexplorer.config.properties + +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType +import dev.fyloz.trial.colorrecipesexplorer.model.materialType +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.stereotype.Component +import org.springframework.util.Assert + +@Component +@ConfigurationProperties(prefix = "entities.material-types") +class MaterialTypeProperties { + var systemTypes: MutableList = mutableListOf() + var baseName: String = "" + + data class MaterialTypeProperty( + var name: String = "", + var prefix: String = "", + var usePercentages: Boolean = false + ) { + fun toMaterialType(): MaterialType { + Assert.hasText(name, "A system material type has an empty name") + return materialType(name = name, prefix = prefix, usePercentages = usePercentages, systemType = true) + } + } +} diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/AccountsModel.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/AccountsModel.kt new file mode 100644 index 0000000..28bff1f --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/AccountsModel.kt @@ -0,0 +1,302 @@ +package dev.fyloz.trial.colorrecipesexplorer.model + +import com.fasterxml.jackson.annotation.JsonIgnore +import com.fasterxml.jackson.annotation.JsonProperty +import org.hibernate.annotations.Fetch +import org.hibernate.annotations.FetchMode +import org.springframework.security.core.GrantedAuthority +import org.springframework.security.core.authority.SimpleGrantedAuthority +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder +import org.springframework.security.crypto.password.PasswordEncoder +import java.time.LocalDateTime +import java.util.* +import javax.persistence.* +import javax.validation.constraints.NotBlank +import javax.validation.constraints.NotNull +import javax.validation.constraints.Size + + +private const val EMPLOYEE_ID_NULL_MESSAGE = "Un numéro d'employé est requis" +private const val EMPLOYEE_LAST_NAME_EMPTY_MESSAGE = "Un nom est requis" +private const val EMPLOYEE_FIRST_NAME_EMPTY_MESSAGE = "Un prénom est requis" +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 +data class Employee( + @Id + override val id: Long, + + val firstName: String = "", + + val lastName: String = "", + + @JsonIgnore + val password: String = "", + + @JsonIgnore + val isDefaultGroupUser: Boolean = false, + + @JsonIgnore + val isSystemUser: Boolean = false, + + @field:ManyToOne + @Fetch(FetchMode.SELECT) + var group: EmployeeGroup? = null, + + @Enumerated(EnumType.STRING) + @ElementCollection(fetch = FetchType.EAGER) + @Fetch(FetchMode.SUBSELECT) + @get:JsonIgnore + val permissions: MutableSet = mutableSetOf(), + + val lastLoginTime: LocalDateTime? = null +) : Model { + @JsonProperty("permissions") + fun getFlattenedPermissions(): Iterable = getPermissions() + + override fun equals(other: Any?): Boolean = other is Employee && id == other.id && firstName == other.firstName && lastName == other.lastName + override fun hashCode(): Int = Objects.hash(id, firstName, lastName) +} + +/** DTO for creating employees. Allows a [password] a [groupId]. */ +open class EmployeeSaveDto( + @field:NotNull(message = EMPLOYEE_ID_NULL_MESSAGE) + val id: Long, + + @field:NotBlank(message = EMPLOYEE_FIRST_NAME_EMPTY_MESSAGE) + val firstName: String, + + @field:NotBlank(message = EMPLOYEE_LAST_NAME_EMPTY_MESSAGE) + val lastName: String, + + @field:NotBlank(message = EMPLOYEE_PASSWORD_EMPTY_MESSAGE) + @field:Size(min = 8, message = EMPLOYEE_PASSWORD_TOO_SHORT_MESSAGE) + val password: String, + + @field:ManyToOne + @Fetch(FetchMode.SELECT) + var groupId: Long? = null, + + @Enumerated(EnumType.STRING) + val permissions: MutableSet = mutableSetOf() +) : EntityDto { + override fun toEntity(): Employee = + Employee(id, firstName, lastName, "", isDefaultGroupUser = false, isSystemUser = false, group = null, permissions = permissions) +} + +open class EmployeeUpdateDto( + @field:NotNull(message = EMPLOYEE_ID_NULL_MESSAGE) + val id: Long, + + @field:NotBlank(message = EMPLOYEE_FIRST_NAME_EMPTY_MESSAGE) + val firstName: String = "", + + @field:NotBlank(message = EMPLOYEE_LAST_NAME_EMPTY_MESSAGE) + val lastName: String = "", + + @Enumerated(EnumType.STRING) + val permissions: Set = mutableSetOf() +) : EntityDto { + override fun toEntity(): Employee = + Employee(id, firstName, lastName, permissions = permissions.toMutableSet()) +} + + +private const val GROUP_ID_NULL_MESSAGE = "Un identifiant est requis" +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 +data class EmployeeGroup( + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + override var id: Long? = null, + + @Column(unique = true) + override val name: String = "", + + @Enumerated(EnumType.STRING) + @ElementCollection(fetch = FetchType.EAGER) + val permissions: MutableSet = mutableSetOf(), + + @OneToMany + @JsonIgnore + val employees: MutableSet = mutableSetOf() +) : NamedModel { + fun getEmployeeCount() = employees.size + + override fun equals(other: Any?): Boolean = other is EmployeeGroup && id == other.id && name == other.name + override fun hashCode(): Int = Objects.hash(id, name) +} + +open class EmployeeGroupSaveDto( + @field:NotBlank(message = GROUP_NAME_NULL_MESSAGE) + @field:Size(min = 3) + val name: String, + + @field:Size(min = 1, message = GROUP_PERMISSIONS_EMPTY_MESSAGE) + val permissions: MutableSet +) : EntityDto { + override fun toEntity(): EmployeeGroup = + EmployeeGroup(null, name, permissions) +} + +open class EmployeeGroupUpdateDto( + @field:NotNull(message = GROUP_ID_NULL_MESSAGE) + val id: Long, + + @field:NotBlank(message = GROUP_NAME_NULL_MESSAGE) + @field:Size(min = 3) + val name: String, + + @field:Size(min = 1, message = GROUP_PERMISSIONS_EMPTY_MESSAGE) + val permissions: MutableSet +) : EntityDto { + override fun toEntity(): EmployeeGroup = + EmployeeGroup(id, name, permissions) +} + + +data class EmployeeLoginRequest(val id: Long, val password: String) + + +enum class EmployeePermission(val impliedPermissions: List = listOf()) { + // View + VIEW_EMPLOYEE, + VIEW_EMPLOYEE_GROUP, + VIEW(listOf( + + )), + + // Edit + EDIT_EMPLOYEE(listOf(VIEW_EMPLOYEE)), + EDIT_EMPLOYEE_PASSWORD(listOf(EDIT_EMPLOYEE)), + EDIT_EMPLOYEE_GROUP(listOf(VIEW_EMPLOYEE_GROUP)), + EDIT(listOf( + VIEW + )), + + // Remove + REMOVE_EMPLOYEE(listOf(EDIT_EMPLOYEE)), + REMOVE_EMPLOYEE_GROUP(listOf(EDIT_EMPLOYEE_GROUP)), + REMOVE(listOf( + EDIT + )), + + // Others + SET_BROWSER_DEFAULT_GROUP(listOf( + VIEW_EMPLOYEE_GROUP + )), + + ADMIN(listOf( + REMOVE, + SET_BROWSER_DEFAULT_GROUP, + + // Admin only permissions + REMOVE_EMPLOYEE, + EDIT_EMPLOYEE_PASSWORD, + REMOVE_EMPLOYEE_GROUP, + )); + + operator fun contains(permission: EmployeePermission): Boolean { + return permission == this || impliedPermissions.any { permission in it } + } +} + +/** Gets [GrantedAuthority]s of the given [Employee]. */ +fun Employee.getAuthorities(): MutableCollection { + return getPermissions().map { it.toAuthority() }.toMutableSet() +} + +/** Gets [EmployeePermission]s of the given [Employee]. */ +fun Employee.getPermissions(): Iterable { + val grantedPermissions: MutableSet = mutableSetOf() + if (group != null) grantedPermissions.addAll(group!!.permissions.flatMap { it.flat() }) + grantedPermissions.addAll(permissions.flatMap { it.flat() }) + return grantedPermissions +} + +private fun EmployeePermission.flat(): Iterable { + return mutableSetOf(this).apply { + impliedPermissions.forEach { + addAll(it.flat()) + } + } +} + +/** Converts the given [EmployeePermission] to a [GrantedAuthority]. */ +private fun EmployeePermission.toAuthority(): GrantedAuthority { + return SimpleGrantedAuthority(name) +} + + +// ==== DSL ==== +fun employee( + passwordEncoder: PasswordEncoder = BCryptPasswordEncoder(), + id: Long = 0L, + firstName: String = "firstName", + lastName: String = "lastName", + password: String = passwordEncoder.encode("password"), + isDefaultGroupUser: Boolean = false, + isSystemUser: Boolean = false, + group: EmployeeGroup? = null, + permissions: MutableSet = mutableSetOf(), + lastLoginTime: LocalDateTime? = null, + op: Employee.() -> Unit = {} +) = Employee(id, firstName, lastName, password, isDefaultGroupUser, isSystemUser, group, permissions, lastLoginTime).apply(op) + +fun employee( + employee: Employee, + newId: Long? = null +) = with(employee) { + Employee(newId + ?: id, firstName, lastName, password, isDefaultGroupUser, isSystemUser, group, permissions, lastLoginTime) +} + +fun employeeSaveDto( + passwordEncoder: PasswordEncoder = BCryptPasswordEncoder(), + id: Long = 0L, + firstName: String = "firstName", + lastName: String = "lastName", + password: String = passwordEncoder.encode("password"), + groupId: Long? = null, + permissions: MutableSet = mutableSetOf(), + op: EmployeeSaveDto.() -> Unit = {} +) = EmployeeSaveDto(id, firstName, lastName, password, groupId, permissions).apply(op) + +fun employeeUpdateDto( + id: Long = 0L, + firstName: String = "firstName", + lastName: String = "lastName", + permissions: MutableSet = mutableSetOf(), + op: EmployeeUpdateDto.() -> Unit = {} +) = EmployeeUpdateDto(id, firstName, lastName, permissions).apply(op) + +fun employeeGroup( + id: Long? = null, + name: String = "name", + permissions: MutableSet = mutableSetOf(), + employees: MutableSet = mutableSetOf(), + op: EmployeeGroup.() -> Unit = {} +) = EmployeeGroup(id, name, permissions, employees).apply(op) + +fun employeeGroup( + employeeGroup: EmployeeGroup, + newId: Long? = null, + newName: String? = null +) = with(employeeGroup) { EmployeeGroup(newId ?: id, newName ?: name, permissions, employees) } + +fun employeeGroupSaveDto( + name: String = "name", + permissions: MutableSet = mutableSetOf(), + op: EmployeeGroupSaveDto.() -> Unit = {} +) = EmployeeGroupSaveDto(name, permissions).apply(op) + +fun employeeGroupUpdateDto( + id: Long = 0L, + name: String = "name", + permissions: MutableSet = mutableSetOf(), + op: EmployeeGroupUpdateDto.() -> Unit = {} +) = EmployeeGroupUpdateDto(id, name, permissions).apply(op) + diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Material.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Material.kt new file mode 100644 index 0000000..42b3185 --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Material.kt @@ -0,0 +1,125 @@ +package dev.fyloz.trial.colorrecipesexplorer.model + +import dev.fyloz.trial.colorrecipesexplorer.model.validation.NullOrNotBlank +import dev.fyloz.trial.colorrecipesexplorer.model.validation.NullOrSize +import org.springframework.util.Assert +import org.springframework.web.multipart.MultipartFile +import java.util.* +import javax.persistence.* +import javax.validation.constraints.NotBlank +import javax.validation.constraints.NotNull +import javax.validation.constraints.Size + +private const val MATERIAL_ID_NULL_MESSAGE = "Un identifiant est requis" +private const val MATERIAL_NAME_NULL_MESSAGE = "Un nom est requis" +private const val MATERIAL_INVENTORY_QUANTITY_NULL_MESSAGE = "Une quantité est requise" +private const val MATERIAL_INVENTORY_QUANTITY_NEGATIVE_MESSAGE = "La quantité doit être supérieure ou égale à 0" +private const val MATERIAL_TYPE_NULL_MESSAGE = "Un type de produit est requis" + +@Entity +data class Material( + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + override val id: Long?, + + @Column(unique = true) + override var name: String, + + var inventoryQuantity: Float, + + val isMixType: Boolean, + + @ManyToOne + var materialType: MaterialType? +) : NamedModel { + 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 + override fun hashCode(): Int = Objects.hash(name) +} + +open class MaterialSaveDto( + @field:NotBlank(message = MATERIAL_NAME_NULL_MESSAGE) + val name: String, + + @field:NotNull(message = MATERIAL_INVENTORY_QUANTITY_NULL_MESSAGE) + @field:Size(min = 0, message = MATERIAL_INVENTORY_QUANTITY_NEGATIVE_MESSAGE) + val inventoryQuantity: Float, + + @field:NotNull(message = MATERIAL_TYPE_NULL_MESSAGE) + val materialType: MaterialType, + + 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:NullOrNotBlank(message = MATERIAL_NAME_NULL_MESSAGE) + val name: String?, + + @field:NullOrSize(min = 0, message = MATERIAL_INVENTORY_QUANTITY_NEGATIVE_MESSAGE) + val inventoryQuantity: Float?, + + val materialType: MaterialType?, + + val simdutFile: MultipartFile? = null +) : EntityDto { + 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 +) + +fun Material.toInventoryMaterial(minimumQuantity: Float): InventoryMaterial { + Assert.notNull(id, "Cannot convert a material without id to an inventory material") + Assert.notNull(name, "Cannot convert a material without name to an inventory material") + Assert.notNull(materialType, "Cannot convert a material without a material type to an inventory material") + return InventoryMaterial(id!!, name, inventoryQuantity, materialType!!.name, inventoryQuantity < minimumQuantity) +} + +// ==== DSL ==== +fun material( + 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) + +fun materialSaveDto( + 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 = {} +) = 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 new file mode 100644 index 0000000..2487102 --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MaterialType.kt @@ -0,0 +1,98 @@ +package dev.fyloz.trial.colorrecipesexplorer.model + +import dev.fyloz.trial.colorrecipesexplorer.model.validation.NullOrNotBlank +import dev.fyloz.trial.colorrecipesexplorer.model.validation.NullOrSize +import org.hibernate.annotations.ColumnDefault +import java.util.* +import javax.persistence.* +import javax.validation.constraints.NotBlank +import javax.validation.constraints.NotNull +import javax.validation.constraints.Size + +private const val MATERIAL_TYPE_ID_NULL_MESSAGE = "Un identifiant est requis" +private const val MATERIAL_TYPE_NAME_NULL_MESSAGE = "Un nom est requis" +private const val MATERIAL_TYPE_PREFIX_NULL_MESSAGE = "Un préfixe est requis" +private const val MATERIAL_TYPE_PREFIX_SIZE_MESSAGE = "Le préfixe doit faire exactement 3 caractères" + +const val IDENTIFIER_PREFIX_NAME = "prefix" + +@Entity +data class MaterialType( + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + override val id: Long? = null, + + @Column(unique = true) + override val name: String = "", + + @Column(unique = true) + val prefix: String = "", + + @ColumnDefault("false") + val usePercentages: Boolean = false, + + @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_PREFIX_NULL_MESSAGE) + @field:Size(min = 3, max = 3, message = MATERIAL_TYPE_PREFIX_SIZE_MESSAGE) + val prefix: String, + + val usePercentages: Boolean = false +) : EntityDto { + override fun toEntity(): MaterialType = + MaterialType(null, name, prefix, usePercentages) +} + +open class MaterialTypeUpdateDto( + @field:NotNull(message = MATERIAL_TYPE_ID_NULL_MESSAGE) + val id: Long, + + @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? +) : EntityDto { + override fun toEntity(): MaterialType = + 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 = {} +) = 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) } + +fun materialTypeSaveDto( + 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 = {} +) = MaterialTypeUpdateDto(id, name, prefix).apply(op) diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Model.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Model.kt new file mode 100644 index 0000000..ce7f1e8 --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Model.kt @@ -0,0 +1,14 @@ +package dev.fyloz.trial.colorrecipesexplorer.model + +interface Model { + val id: Long? +} + +interface NamedModel : Model { + val name: String +} + +interface EntityDto { + /** Converts the dto to an actual entity. */ + fun toEntity(): E +} diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/validation/NullOrNotBlank.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/validation/NullOrNotBlank.kt new file mode 100644 index 0000000..476143f --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/validation/NullOrNotBlank.kt @@ -0,0 +1,32 @@ +package dev.fyloz.trial.colorrecipesexplorer.model.validation + +import javax.validation.Constraint +import javax.validation.ConstraintValidator +import javax.validation.ConstraintValidatorContext +import javax.validation.Payload +import kotlin.reflect.KClass + +private const val MESSAGE = "must be null or not blank" + +@Target(AnnotationTarget.FIELD) +@MustBeDocumented +@Constraint(validatedBy = [NullOrNotBlankValidator::class]) +annotation class NullOrNotBlank( + val message: String = MESSAGE, + val groups: Array> = [], + val payload: Array> = [] +) + +class NullOrNotBlankValidator : ConstraintValidator { + var message = MESSAGE + + override fun initialize(constraintAnnotation: NullOrNotBlank) { + message = constraintAnnotation.message + } + + override fun isValid(value: String?, context: ConstraintValidatorContext): Boolean { + return (value == null || value.isNotBlank()).apply { + if (!this) context.buildConstraintViolationWithTemplate(message) + } + } +} diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/validation/NullOrSize.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/validation/NullOrSize.kt new file mode 100644 index 0000000..192960f --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/validation/NullOrSize.kt @@ -0,0 +1,46 @@ +package dev.fyloz.trial.colorrecipesexplorer.model.validation + +import javax.validation.Constraint +import javax.validation.ConstraintValidator +import javax.validation.ConstraintValidatorContext +import javax.validation.Payload +import kotlin.reflect.KClass + +private const val MIN_SIZE = Long.MIN_VALUE +private const val MAX_SIZE = Long.MAX_VALUE +private const val MESSAGE = "must be null or have a correct length" + +@Target(AnnotationTarget.FIELD) +@MustBeDocumented +@Constraint(validatedBy = [NullOrSizeValidator::class]) +annotation class NullOrSize( + val min: Long = MIN_SIZE, + val max: Long = MAX_SIZE, + val message: String = MESSAGE, + val groups: Array> = [], + val payload: Array> = [] +) + +class NullOrSizeValidator : ConstraintValidator { + var min = MIN_SIZE + var max = MAX_SIZE + var message = MESSAGE + + override fun initialize(constraintAnnotation: NullOrSize) { + min = constraintAnnotation.min + max = constraintAnnotation.max + message = constraintAnnotation.message + } + + override fun isValid(value: Any?, context: ConstraintValidatorContext): Boolean { + if (value == null) return true + return when (value) { + is Number -> value.toLong() in min..max + is String -> value.length in min..max + is Collection<*> -> value.size in min..max + else -> throw IllegalStateException("Cannot use @NullOrSize on type ${value::class}") + }.apply { + if (!this) context.buildConstraintViolationWithTemplate(message) + } + } +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/EmployeeRepository.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/AccountRepository.kt similarity index 52% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/EmployeeRepository.kt rename to src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/AccountRepository.kt index 03f1aaa..975a69a 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/dao/EmployeeRepository.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/AccountRepository.kt @@ -1,7 +1,7 @@ -package dev.fyloz.trial.colorrecipesexplorer.dao +package dev.fyloz.trial.colorrecipesexplorer.repository -import dev.fyloz.trial.colorrecipesexplorer.core.model.Employee -import dev.fyloz.trial.colorrecipesexplorer.core.model.EmployeeGroup +import dev.fyloz.trial.colorrecipesexplorer.model.Employee +import dev.fyloz.trial.colorrecipesexplorer.model.EmployeeGroup import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository @@ -11,14 +11,10 @@ interface EmployeeRepository : JpaRepository { fun findByFirstNameAndLastName(firstName: String, lastName: String): Employee? - fun findByGroup(group: EmployeeGroup): Collection + fun findAllByGroup(group: EmployeeGroup): Collection fun findByIsDefaultGroupUserIsTrueAndGroupIs(group: EmployeeGroup): Employee } @Repository -interface EmployeeGroupRepository : JpaRepository { - fun existsByName(name: String): Boolean - - fun findByName(name: String): EmployeeGroup? -} +interface EmployeeGroupRepository : NamedJpaRepository diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialRepository.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialRepository.kt new file mode 100644 index 0000000..13a36bf --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialRepository.kt @@ -0,0 +1,14 @@ +package dev.fyloz.trial.colorrecipesexplorer.repository + +import dev.fyloz.trial.colorrecipesexplorer.model.Material +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType +import org.springframework.stereotype.Repository + +@Repository +interface MaterialRepository : NamedJpaRepository { + /** Checks if one or more materials have the given [materialType]. */ + fun existsByMaterialType(materialType: MaterialType): Boolean + + /** Gets all the materials with the given [materialType]. */ + fun findAllByMaterialType(materialType: MaterialType): Collection +} diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialTypeRepository.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialTypeRepository.kt new file mode 100644 index 0000000..14b2870 --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialTypeRepository.kt @@ -0,0 +1,16 @@ +package dev.fyloz.trial.colorrecipesexplorer.repository + +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType +import org.springframework.stereotype.Repository + +@Repository +interface MaterialTypeRepository : NamedJpaRepository { + /** Checks if a material type exists with the given [prefix]. */ + fun existsByPrefix(prefix: String): Boolean + + /** Gets all material types which are not system types. */ + fun findAllBySystemTypeIs(value: Boolean): Collection + + /** Gets the material type with the given [prefix]. */ + fun findByPrefix(prefix: String): MaterialType? +} diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/Repository.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/Repository.kt new file mode 100644 index 0000000..4cc8ba7 --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/Repository.kt @@ -0,0 +1,18 @@ +package dev.fyloz.trial.colorrecipesexplorer.repository + +import dev.fyloz.trial.colorrecipesexplorer.model.NamedModel +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.repository.NoRepositoryBean + +/** Adds support for entities using a name identifier. */ +@NoRepositoryBean +interface NamedJpaRepository : JpaRepository { + /** Checks if an entity with the given [name]. */ + fun existsByName(name: String): Boolean + + /** Gets the entity with the given [name]. */ + fun findByName(name: String): E? + + /** Removes the entity with the given [name]. */ + fun deleteByName(name: String) +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/rest/AccountsControllers.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/AccountControllers.kt similarity index 74% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/rest/AccountsControllers.kt rename to src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/AccountControllers.kt index 4339a11..2e8e9c3 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/rest/AccountsControllers.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/AccountControllers.kt @@ -1,21 +1,16 @@ package dev.fyloz.trial.colorrecipesexplorer.rest -import dev.fyloz.trial.colorrecipesexplorer.core.model.Employee -import dev.fyloz.trial.colorrecipesexplorer.core.model.EmployeeDto -import dev.fyloz.trial.colorrecipesexplorer.core.model.EmployeeGroup -import dev.fyloz.trial.colorrecipesexplorer.core.model.EmployeePermission -import dev.fyloz.trial.colorrecipesexplorer.core.services.EmployeeGroupService -import dev.fyloz.trial.colorrecipesexplorer.core.services.EmployeeService +import dev.fyloz.trial.colorrecipesexplorer.service.EmployeeGroupServiceImpl +import dev.fyloz.trial.colorrecipesexplorer.service.EmployeeServiceImpl +import dev.fyloz.trial.colorrecipesexplorer.model.* import org.springframework.context.annotation.Profile import org.springframework.http.HttpStatus import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* -import java.net.URI import java.security.Principal import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse -import javax.validation.Valid private const val EMPLOYEE_CONTROLLER_PATH = "api/employee" private const val EMPLOYEE_GROUP_CONTROLLER_PATH = "api/employee/group" @@ -23,25 +18,12 @@ private const val EMPLOYEE_GROUP_CONTROLLER_PATH = "api/employee/group" @RestController @RequestMapping(EMPLOYEE_CONTROLLER_PATH) @Profile("rest") -class EmployeeController(employeeService: EmployeeService) : - AbstractRestModelController(employeeService, EMPLOYEE_CONTROLLER_PATH) { +class EmployeeController(employeeService: EmployeeServiceImpl) : + AbstractRestModelApiController(employeeService, EMPLOYEE_CONTROLLER_PATH) { @GetMapping("current") @ResponseStatus(HttpStatus.OK) fun getCurrent(loggedInEmployee: Principal): ResponseEntity = ResponseEntity.ok(service.getById(loggedInEmployee.name.toLong(), ignoreDefaultGroupUsers = false, ignoreSystemUsers = false)) - @PostMapping - @ResponseStatus(HttpStatus.CREATED) - fun save(@Valid @RequestBody employee: EmployeeDto): ResponseEntity { - val saved = service.save(employee) - return ResponseEntity - .created(URI("$controllerPath/${getEntityId(saved)}")) - .body(saved) - } - - @PostMapping("create") - @ResponseStatus(HttpStatus.NOT_FOUND) - override fun save(entity: Employee): ResponseEntity = ResponseEntity.notFound().build() - @PutMapping("{id}/password", consumes = [MediaType.TEXT_PLAIN_VALUE]) @ResponseStatus(HttpStatus.NO_CONTENT) fun updatePassword(@PathVariable id: Long, @RequestBody password: String): ResponseEntity { @@ -80,8 +62,8 @@ class EmployeeController(employeeService: EmployeeService) : @RestController @RequestMapping(EMPLOYEE_GROUP_CONTROLLER_PATH) @Profile("rest") -class GroupsController(groupService: EmployeeGroupService) : - AbstractRestModelController(groupService, EMPLOYEE_GROUP_CONTROLLER_PATH) { +class GroupsController(groupService: EmployeeGroupServiceImpl) : + AbstractRestModelApiController(groupService, EMPLOYEE_GROUP_CONTROLLER_PATH) { @GetMapping("{id}/employees") @ResponseStatus(HttpStatus.OK) fun getEmployeesForGroup(@PathVariable id: Long): ResponseEntity> = ResponseEntity.ok(service.getEmployeesForGroup(id)) diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/InventoryController.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/InventoryController.kt new file mode 100644 index 0000000..8abf418 --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/InventoryController.kt @@ -0,0 +1,11 @@ +package dev.fyloz.trial.colorrecipesexplorer.rest + +import dev.fyloz.trial.colorrecipesexplorer.model.InventoryMaterial +import dev.fyloz.trial.colorrecipesexplorer.service.InventoryService +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.RestController + +@RestController +class InventoryController(val inventoryService: InventoryService) { + fun getAllMaterials(): ResponseEntity> = ResponseEntity.ok(inventoryService.getAllMaterials()) +} diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/MaterialController.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/MaterialController.kt new file mode 100644 index 0000000..4657207 --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/MaterialController.kt @@ -0,0 +1,28 @@ +package dev.fyloz.trial.colorrecipesexplorer.rest + +import dev.fyloz.trial.colorrecipesexplorer.model.Material +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialSaveDto +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialUpdateDto +import dev.fyloz.trial.colorrecipesexplorer.service.MaterialService +import org.springframework.context.annotation.Profile +import org.springframework.http.MediaType +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.PutMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +private const val MATERIAL_CONTROLLER_PATH = "api/material" + +@RestController +@RequestMapping(MATERIAL_CONTROLLER_PATH) +@Profile("rest") +class MaterialController(materialService: MaterialService) : AbstractRestModelApiController(materialService, MATERIAL_CONTROLLER_PATH) { + @PostMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) + override fun save(entity: MaterialSaveDto): ResponseEntity = super.save(entity) + + @PutMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) + override fun update(entity: MaterialUpdateDto): ResponseEntity { + return super.update(entity) + } +} diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/MaterialTypeController.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/MaterialTypeController.kt new file mode 100644 index 0000000..2827b00 --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/MaterialTypeController.kt @@ -0,0 +1,20 @@ +package dev.fyloz.trial.colorrecipesexplorer.rest + +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialTypeSaveDto +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialTypeUpdateDto +import dev.fyloz.trial.colorrecipesexplorer.service.MaterialTypeService +import org.springframework.context.annotation.Profile +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + + +private const val MATERIAL_TYPE_CONTROLLER_PATH = "api/materialtype" + +@RestController +@RequestMapping(MATERIAL_TYPE_CONTROLLER_PATH) +@Profile("rest") +class MaterialTypeController(materialTypeService: MaterialTypeService) : + AbstractRestModelApiController(materialTypeService, MATERIAL_TYPE_CONTROLLER_PATH) { + +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/rest/RestController.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/RestApiController.kt similarity index 62% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/rest/RestController.kt rename to src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/RestApiController.kt index dc69700..1cc1fd5 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/rest/RestController.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/rest/RestApiController.kt @@ -1,30 +1,30 @@ package dev.fyloz.trial.colorrecipesexplorer.rest -import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel -import dev.fyloz.trial.colorrecipesexplorer.core.services.IGenericModelService -import dev.fyloz.trial.colorrecipesexplorer.core.services.IGenericService +import dev.fyloz.trial.colorrecipesexplorer.model.EntityDto +import dev.fyloz.trial.colorrecipesexplorer.model.Model +import dev.fyloz.trial.colorrecipesexplorer.service.ModelService +import dev.fyloz.trial.colorrecipesexplorer.service.Service import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity -import org.springframework.security.access.prepost.PreAuthorize import org.springframework.web.bind.annotation.* import java.net.URI import javax.validation.Valid -interface IRestController { +interface RestApiController, U : EntityDto> { @ResponseStatus(HttpStatus.OK) fun getAll(): ResponseEntity> @ResponseStatus(HttpStatus.CREATED) - fun save(entity: E): ResponseEntity + fun save(entity: S): ResponseEntity @ResponseStatus(HttpStatus.NO_CONTENT) - fun update(entity: E): ResponseEntity + fun update(entity: U): ResponseEntity @ResponseStatus(HttpStatus.NO_CONTENT) fun delete(entity: E): ResponseEntity } -interface IRestModelController : IRestController { +interface RestModelApiController, U : EntityDto> : RestApiController { @ResponseStatus(HttpStatus.OK) fun getById(id: Long): ResponseEntity @@ -32,15 +32,15 @@ interface IRestModelController : IRestController { fun deleteById(id: Long): ResponseEntity } -abstract class AbstractRestController>(val service: S, protected val controllerPath: String) : - IRestController { +abstract class AbstractRestApiController, U : EntityDto, S : Service>(val service: S, protected val controllerPath: String) : + RestApiController { protected abstract fun getEntityId(entity: E): Any? @GetMapping override fun getAll(): ResponseEntity> = ResponseEntity.ok(service.getAll()) @PostMapping - override fun save(@Valid @RequestBody entity: E): ResponseEntity { + override fun save(@Valid @RequestBody entity: N): ResponseEntity { val saved = service.save(entity) return ResponseEntity .created(URI("$controllerPath/${getEntityId(saved)}")) @@ -48,7 +48,7 @@ abstract class AbstractRestController>(val service: S, } @PutMapping - override fun update(@Valid @RequestBody entity: E): ResponseEntity { + override fun update(@Valid @RequestBody entity: U): ResponseEntity { service.update(entity) return ResponseEntity .noContent() @@ -64,8 +64,8 @@ abstract class AbstractRestController>(val service: S, } } -abstract class AbstractRestModelController>(service: S, controllerPath: String) : - AbstractRestController(service, controllerPath), IRestModelController { +abstract class AbstractRestModelApiController, U : EntityDto, S : ModelService>(service: S, controllerPath: String) : + AbstractRestApiController(service, controllerPath), RestModelApiController { override fun getEntityId(entity: E) = entity.id @GetMapping("{id}") diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/AccountsService.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AccountService.kt similarity index 52% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/AccountsService.kt rename to src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AccountService.kt index e3edb72..96382a8 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/AccountsService.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AccountService.kt @@ -1,12 +1,15 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services +package dev.fyloz.trial.colorrecipesexplorer.service -import dev.fyloz.trial.colorrecipesexplorer.core.configuration.SecurityConfigurationProperties -import dev.fyloz.trial.colorrecipesexplorer.core.configuration.blacklistedJwtTokens -import dev.fyloz.trial.colorrecipesexplorer.core.configuration.defaultGroupCookieName -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.* -import dev.fyloz.trial.colorrecipesexplorer.core.model.* -import dev.fyloz.trial.colorrecipesexplorer.dao.EmployeeGroupRepository -import dev.fyloz.trial.colorrecipesexplorer.dao.EmployeeRepository +import dev.fyloz.trial.colorrecipesexplorer.config.SecurityConfigurationProperties +import dev.fyloz.trial.colorrecipesexplorer.config.blacklistedJwtTokens +import dev.fyloz.trial.colorrecipesexplorer.config.defaultGroupCookieName +import dev.fyloz.trial.colorrecipesexplorer.repository.EmployeeGroupRepository +import dev.fyloz.trial.colorrecipesexplorer.repository.EmployeeRepository +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsRestException +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundException +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundRestException +import dev.fyloz.trial.colorrecipesexplorer.model.* +import io.jsonwebtoken.lang.Assert import org.springframework.beans.factory.annotation.Autowired import org.springframework.security.core.userdetails.User import org.springframework.security.core.userdetails.UserDetails @@ -20,67 +23,135 @@ import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse import javax.transaction.Transactional -@Service -class EmployeeService(val employeeRepository: EmployeeRepository, val passwordEncoder: PasswordEncoder) : - AbstractModelService(employeeRepository, Employee::class.java) { - @Autowired - lateinit var groupService: EmployeeGroupService - +interface EmployeeService : ModelService { /** Check if an [Employee] with the given [firstName] and [lastName] exists. */ - fun existsByFirstNameAndLastName(firstName: String, lastName: String): Boolean { - return repository.existsByFirstNameAndLastName(firstName, lastName) - } - - override fun getAll(): Collection { - return super.getAll().filter { !it.isSystemUser && !it.isDefaultGroupUser } - } - - override fun getById(id: Long): Employee { - return getById(id, ignoreDefaultGroupUsers = true, ignoreSystemUsers = true) - } + fun existsByFirstNameAndLastName(firstName: String, lastName: String): Boolean /** Gets the employee with the given [id]. */ - fun getById(id: Long, ignoreDefaultGroupUsers: Boolean, ignoreSystemUsers: Boolean): Employee { - return super.getById(id).apply { - if (ignoreSystemUsers && isSystemUser || ignoreDefaultGroupUsers && isDefaultGroupUser) throw EntityNotFoundRestException(id) - } - } + fun getById(id: Long, ignoreDefaultGroupUsers: Boolean, ignoreSystemUsers: Boolean): Employee /** Gets all employees which have the given [group]. */ - fun getByGroup(group: EmployeeGroup): Collection { - return repository.findByGroup(group).filter { !it.isSystemUser && !it.isDefaultGroupUser } - } + fun getByGroup(group: EmployeeGroup): Collection /** Gets the default user of the given [group]. */ - fun getDefaultGroupUser(group: EmployeeGroup): Employee { - return repository.findByIsDefaultGroupUserIsTrueAndGroupIs(group) - } + fun getDefaultGroupEmployee(group: EmployeeGroup): Employee - /** Saves the given [employee]. The password contained in the DTO will be hashed in the created [Employee]. */ - fun save(employee: EmployeeDto): Employee { - return save(with(employee) { - Employee(id, firstName, lastName, passwordEncoder.encode(password), isDefaultGroupUser = false, isSystemUser = false, group = if (groupId != null) groupService.getById(groupId!!) else null, permissions = permissions) - }) - } + /** Save a default group employee for the given [group]. */ + fun saveDefaultGroupEmployee(group: EmployeeGroup) + + /** Updates de given [entity]. **/ + fun update(entity: Employee, ignoreDefaultGroupUsers: Boolean, ignoreSystemUsers: Boolean): Employee + + /** Updates the last login time of the employee with the given [employeeId]. */ + fun updateLastLoginTime(employeeId: Long, time: LocalDateTime = LocalDateTime.now()): Employee + + /** Updates the password of the employee with the given [id]. */ + fun updatePassword(id: Long, password: String): Employee + + /** Adds the given [permission] to the employee with the given [employeeId]. */ + fun addPermission(employeeId: Long, permission: EmployeePermission): Employee + + /** Removes the given [permission] from the employee with the given [employeeId]. */ + fun removePermission(employeeId: Long, permission: EmployeePermission): Employee + + /** Logout an user. Add the authorization token of the given [request] to the blacklisted tokens. */ + fun logout(request: HttpServletRequest) +} + +interface EmployeeGroupService : ModelService { + /** Checks if a group with the given [name] exists. */ + fun existsByName(name: String): Boolean + + /** Gets all the employees of the group with the given [id]. */ + fun getEmployeesForGroup(id: Long): Collection + + /** Gets the default group from a cookie in the given HTTP [request]. */ + fun getRequestDefaultGroup(request: HttpServletRequest): EmployeeGroup + + /** Sets the default group cookie for the given HTTP [response]. */ + fun setResponseDefaultGroup(groupId: Long, response: HttpServletResponse) + + /** Adds the employee with the given [employeeId] to the group with the given [groupId]. */ + fun addEmployeeToGroup(groupId: Long, employeeId: Long) + + /** + * Adds a given [employee] to a given [group]. + * + * If the [employee] is already in the [group], nothing will be done. + * If the [employee] is already in a group, it will be removed from it. + */ + fun addEmployeeToGroup(group: EmployeeGroup, employee: Employee) + + /** Removes the employee with the given [employeeId] from the group with the given [groupId]. */ + fun removeEmployeeFromGroup(groupId: Long, employeeId: Long) + + /** Removes a given [employee] from the given [group]. */ + fun removeEmployeeFromGroup(group: EmployeeGroup, employee: Employee) +} + +interface EmployeeUserDetailsService : UserDetailsService { + /** Loads an [User] for the given [employeeId]. */ + fun loadUserByEmployeeId(employeeId: Long, ignoreDefaultGroupUsers: Boolean = false): UserDetails +} + +@Service +class EmployeeServiceImpl(val employeeRepository: EmployeeRepository, val passwordEncoder: PasswordEncoder) : + AbstractModelService(employeeRepository), + EmployeeService { + @Autowired + lateinit var groupService: EmployeeGroupServiceImpl + + override fun existsByFirstNameAndLastName(firstName: String, lastName: String): Boolean = + repository.existsByFirstNameAndLastName(firstName, lastName) + + override fun getAll(): Collection = + super.getAll().filter { !it.isSystemUser && !it.isDefaultGroupUser } + + override fun getById(id: Long): Employee = + getById(id, ignoreDefaultGroupUsers = true, ignoreSystemUsers = true) + + override fun getById(id: Long, ignoreDefaultGroupUsers: Boolean, ignoreSystemUsers: Boolean): Employee = + super.getById(id).apply { + if (ignoreSystemUsers && isSystemUser || ignoreDefaultGroupUsers && isDefaultGroupUser) throw EntityNotFoundRestException(id) + } + + override fun getByGroup(group: EmployeeGroup): Collection = + repository.findAllByGroup(group).filter { + !it.isSystemUser && !it.isDefaultGroupUser + } + + override fun getDefaultGroupEmployee(group: EmployeeGroup): Employee = + repository.findByIsDefaultGroupUserIsTrueAndGroupIs(group) + + override fun save(entity: EmployeeSaveDto): Employee = + save(with(entity) { + Employee(id, firstName, lastName, passwordEncoder.encode(password), isDefaultGroupUser = false, isSystemUser = false, group = if (groupId != null) groupService.getById(groupId!!) else null, permissions = permissions) + }) override fun save(entity: Employee): Employee { if (existsByFirstNameAndLastName(entity.firstName, entity.lastName)) - throw EntityAlreadyExistsException(type, ModelException.IdentifierType.NAME, "${entity.firstName} ${entity.lastName}") - + throw EntityAlreadyExistsRestException("${entity.firstName} ${entity.lastName}") return super.save(entity) } - /** Updates the last login time of the employee with the given [employeeId]. */ - fun updateLastLoginTime(employeeId: Long) { - update(Employee(id = employeeId, lastLoginTime = LocalDateTime.now()), ignoreDefaultGroupUsers = true, ignoreSystemUsers = false) + override fun saveDefaultGroupEmployee(group: EmployeeGroup) { + save(Employee( + id = 1000000L + group.id!!, + firstName = group.name, + lastName = "EmployeeModel", + password = passwordEncoder.encode(group.name), + group = group, + isDefaultGroupUser = true + )) } - override fun update(entity: Employee): Employee { - return update(entity, ignoreDefaultGroupUsers = true, ignoreSystemUsers = true) - } + override fun updateLastLoginTime(employeeId: Long, time: LocalDateTime): Employee = + update(Employee(id = employeeId, lastLoginTime = time), ignoreDefaultGroupUsers = true, ignoreSystemUsers = false) - /** Updates de given [entity]. **/ - fun update(entity: Employee, ignoreDefaultGroupUsers: Boolean, ignoreSystemUsers: Boolean): Employee { + override fun update(entity: Employee): Employee = + update(entity, ignoreDefaultGroupUsers = true, ignoreSystemUsers = true) + + override fun update(entity: Employee, ignoreDefaultGroupUsers: Boolean, ignoreSystemUsers: Boolean): Employee { val persistedEmployee = getById(entity.id, ignoreDefaultGroupUsers, ignoreSystemUsers) with(repository.findByFirstNameAndLastName(entity.firstName, entity.lastName)) { if (this != null && id != entity.id) @@ -102,10 +173,9 @@ class EmployeeService(val employeeRepository: EmployeeRepository, val passwordEn }) } - /** Updates the password of the employee with the given [id]. */ - fun updatePassword(id: Long, password: String) { + override fun updatePassword(id: Long, password: String): Employee { val persistedEmployee = getById(id, ignoreDefaultGroupUsers = true, ignoreSystemUsers = true) - super.update(with(persistedEmployee) { + return super.update(with(persistedEmployee) { Employee( id, firstName, @@ -120,14 +190,13 @@ class EmployeeService(val employeeRepository: EmployeeRepository, val passwordEn }) } - /** Adds the given [permission] to the employee with the given [employeeId]. */ - fun addPermission(employeeId: Long, permission: EmployeePermission) = super.update(getById(employeeId).apply { permissions += permission }) + override fun addPermission(employeeId: Long, permission: EmployeePermission): Employee = + super.update(getById(employeeId).apply { permissions += permission }) - /** Removes the given [permission] from the employee with the given [employeeId]. */ - fun removePermission(employeeId: Long, permission: EmployeePermission) = super.update(getById(employeeId).apply { permissions -= permission }) + override fun removePermission(employeeId: Long, permission: EmployeePermission): Employee = + super.update(getById(employeeId).apply { permissions -= permission }) - /** Logout an user. Add the authorization token of the given [request] to the blacklisted tokens. */ - fun logout(request: HttpServletRequest) { + override fun logout(request: HttpServletRequest) { val authorizationCookie = WebUtils.getCookie(request, "Authorization") if (authorizationCookie != null) { val authorizationToken = authorizationCookie.value @@ -141,41 +210,24 @@ class EmployeeService(val employeeRepository: EmployeeRepository, val passwordEn const val defaultGroupCookieMaxAge = 10 * 365 * 24 * 60 * 60 // 10 ans @Service -class EmployeeGroupService(val employeeGroupRepository: EmployeeGroupRepository, val employeeService: EmployeeService) : AbstractModelService(employeeGroupRepository, EmployeeGroup::class.java) { - /** Checks if a group with the given [name] exists. */ - fun existsByName(name: String): Boolean { - return repository.existsByName(name) - } - - /** Gets all the employees of the group with the given [id]. */ - fun getEmployeesForGroup(id: Long): Collection { - return employeeService.getByGroup(getById(id)) - } +class EmployeeGroupServiceImpl(val employeeGroupRepository: EmployeeGroupRepository, val employeeService: EmployeeService) : + AbstractModelService(employeeGroupRepository), + EmployeeGroupService { + override fun existsByName(name: String): Boolean = repository.existsByName(name) + override fun getEmployeesForGroup(id: Long): Collection = + getById(id).employees @Transactional override fun save(entity: EmployeeGroup): EmployeeGroup { - fun createDefaultGroupUser(group: EmployeeGroup) { - employeeService.save(Employee( - id = 1000000L + group.id!!, - firstName = group.name, - lastName = "Employee", - password = employeeService.passwordEncoder.encode(group.name), - isDefaultGroupUser = true, - group = group - )) + return super.save(entity).apply { + Assert.notNull(id, "Saved employee group has a null identifier") + employeeService.saveDefaultGroupEmployee(this) } - - val group = super.save(entity) - createDefaultGroupUser(group) - return group } override fun update(entity: EmployeeGroup): EmployeeGroup { + Assert.notNull("Updated employee group has a null identifier") val persistedGroup = getById(entity.id!!) - with(repository.findByName(entity.name)) { - if (this != null && id != entity.id) - throw EntityAlreadyExistsRestException(entity.name) - } return super.update(with(entity) { EmployeeGroup( @@ -189,40 +241,31 @@ class EmployeeGroupService(val employeeGroupRepository: EmployeeGroupRepository, @Transactional override fun delete(entity: EmployeeGroup) { - employeeService.delete(employeeService.getDefaultGroupUser(entity)) + employeeService.delete(employeeService.getDefaultGroupEmployee(entity)) super.delete(entity) } - /** Gets the default group cookie for the given HTTP [request]. */ - fun getRequestDefaultGroup(request: HttpServletRequest): EmployeeGroup { + override fun getRequestDefaultGroup(request: HttpServletRequest): EmployeeGroup { val defaultGroupCookie = WebUtils.getCookie(request, defaultGroupCookieName) ?: throw EntityNotFoundRestException("defaultGroup") val defaultGroupUser = employeeService.getById(defaultGroupCookie.value.toLong(), ignoreDefaultGroupUsers = false, ignoreSystemUsers = true) return defaultGroupUser.group!! } - /** Sets the default group cookie for the given HTTP [response]. */ - fun setResponseDefaultGroup(groupId: Long, response: HttpServletResponse) { + override fun setResponseDefaultGroup(groupId: Long, response: HttpServletResponse) { val group = getById(groupId) - val defaultGroupUser = employeeService.getDefaultGroupUser(group) + val defaultGroupUser = employeeService.getDefaultGroupEmployee(group) response.addHeader("Set-Cookie", "$defaultGroupCookieName=${defaultGroupUser.id}; Max-Age=${defaultGroupCookieMaxAge}; Path=/api; HttpOnly; Secure; SameSite=strict") } - /** Adds the employee with the given [employeeId] to the group with the given [groupId]. */ - fun addEmployeeToGroup(groupId: Long, employeeId: Long) { + override fun addEmployeeToGroup(groupId: Long, employeeId: Long) { addEmployeeToGroup(getById(groupId), employeeService.getById(employeeId)) } - /** - * Adds a given [employee] to a given [group]. - * - * If the [employee] is already in the [group], nothing will be done. - * If the [employee] is already in a group, it will be removed from it. - */ @Transactional - fun addEmployeeToGroup(group: EmployeeGroup, employee: Employee) { - if (employee.group != null) removeEmployeeFromGroup(employee.group!!, employee) + override fun addEmployeeToGroup(group: EmployeeGroup, employee: Employee) { if (employee.group == group) return + if (employee.group != null) removeEmployeeFromGroup(employee.group!!, employee) group.employees.add(employee) employee.group = group @@ -230,14 +273,12 @@ class EmployeeGroupService(val employeeGroupRepository: EmployeeGroupRepository, employeeService.update(employee) } - /** Removes the employee with the given [employeeId] from the group with the given [groupId]. */ - fun removeEmployeeFromGroup(groupId: Long, employeeId: Long) = + override fun removeEmployeeFromGroup(groupId: Long, employeeId: Long) = removeEmployeeFromGroup(getById(groupId), employeeService.getById(employeeId)) - /** Removes a given [employee] from the given [group]. */ @Transactional - fun removeEmployeeFromGroup(group: EmployeeGroup, employee: Employee) { - if (employee.group == null) return + override fun removeEmployeeFromGroup(group: EmployeeGroup, employee: Employee) { + if (employee.group == null || employee.group != group) return group.employees.remove(employee) employee.group = null @@ -247,7 +288,8 @@ class EmployeeGroupService(val employeeGroupRepository: EmployeeGroupRepository, } @Service -class EmployeeUserDetailsService(val employeeService: EmployeeService, val securityConfigurationProperties: SecurityConfigurationProperties) : UserDetailsService { +class EmployeeUserDetailsServiceImpl(val employeeService: EmployeeService, val securityConfigurationProperties: SecurityConfigurationProperties) : + EmployeeUserDetailsService { override fun loadUserByUsername(username: String): UserDetails { try { return loadUserByEmployeeId(username.toLong(), true) @@ -258,8 +300,7 @@ class EmployeeUserDetailsService(val employeeService: EmployeeService, val secur } } - /** Loads an [User] for the given [employeeId]. */ - fun loadUserByEmployeeId(employeeId: Long, ignoreDefaultGroupUsers: Boolean = false): UserDetails { + override fun loadUserByEmployeeId(employeeId: Long, ignoreDefaultGroupUsers: Boolean): UserDetails { val employee = employeeService.getById(employeeId, ignoreDefaultGroupUsers = ignoreDefaultGroupUsers, ignoreSystemUsers = false) return User(employee.id.toString(), employee.password, employee.getAuthorities()) } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/InventoryService.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/InventoryService.kt similarity index 64% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/InventoryService.kt rename to src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/InventoryService.kt index 53a6463..0a96442 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/InventoryService.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/InventoryService.kt @@ -1,16 +1,19 @@ -package dev.fyloz.trial.colorrecipesexplorer.core.services +package dev.fyloz.trial.colorrecipesexplorer.service -import dev.fyloz.trial.colorrecipesexplorer.core.exception.TooLowQuantityException -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.InventoryDto -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService -import org.springframework.beans.factory.annotation.Autowired +import dev.fyloz.trial.colorrecipesexplorer.exception.TooLowQuantityException +import dev.fyloz.trial.colorrecipesexplorer.model.InventoryMaterial +import dev.fyloz.trial.colorrecipesexplorer.model.Material +import dev.fyloz.trial.colorrecipesexplorer.model.dto.InventoryDto +import dev.fyloz.trial.colorrecipesexplorer.model.toInventoryMaterial import org.springframework.stereotype.Service +const val minimumQuantity = 100.0f // TODO quantity stored in database + @Service -class InventoryService { - @Autowired - lateinit var materialService: MaterialService +class InventoryService(val materialService: MaterialServiceImpl) { + fun getAllMaterials(): Collection { + return materialService.getAllNotMixType().map { it.toInventoryMaterial(minimumQuantity) } + } /** * Use all materials in the given [mixes]. diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialService.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialService.kt new file mode 100644 index 0000000..af04e2c --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialService.kt @@ -0,0 +1,61 @@ +package dev.fyloz.trial.colorrecipesexplorer.service + +import dev.fyloz.trial.colorrecipesexplorer.repository.MaterialRepository +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsRestException +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundRestException +import dev.fyloz.trial.colorrecipesexplorer.model.* +import dev.fyloz.trial.colorrecipesexplorer.service.files.SimdutService +import dev.fyloz.trial.colorrecipesexplorer.service.model.MixQuantityService +import io.jsonwebtoken.lang.Assert +import org.springframework.context.annotation.Profile +import org.springframework.stereotype.Service + +interface MaterialService : NamedModelService { + /** Checks if a material with the given [materialType] exists. */ + fun existsByMaterialType(materialType: MaterialType): Boolean + + /** Checks if the given [material] is used by at least one mix. */ + fun isLinkedToMixes(material: Material): Boolean + + /** Gets all materials that are not a mix type. */ + fun getAllNotMixType(): Collection +} + +@Service +class MaterialServiceImpl(materialRepository: MaterialRepository, val mixQuantityService: MixQuantityService, val simdutService: SimdutService) : + AbstractNamedModelService(materialRepository), + MaterialService { + override fun existsByMaterialType(materialType: MaterialType): Boolean = repository.existsByMaterialType(materialType) + override fun isLinkedToMixes(material: Material): Boolean = mixQuantityService.existsByMaterial(material) + override fun getAllNotMixType(): Collection = getAll().filter { !it.isMixType } + + override fun save(entity: MaterialSaveDto): Material = + save(entity.toMaterial()).apply { + if (entity.simdutFile != null && !entity.simdutFile.isEmpty) simdutService.write(this, entity.simdutFile) + } + + override fun save(entity: Material): Material { + if (existsByName(entity.name)) + throw EntityAlreadyExistsRestException(entity.name) + return super.save(entity) + } + + override fun update(entity: MaterialUpdateDto): Material = + update(entity.toMaterial()).apply { simdutService.update(entity.simdutFile, this) } + + override fun update(entity: Material): Material { + Assert.notNull(entity.id, "MaterialService.update() was called with a null identifier") + val persistedMaterial = getById(entity.id!!) + Assert.notNull(persistedMaterial.materialType, "A persisted material has a null material type") + + return super.update(with(entity) { + material( + id = id!!, + name = if (name.isNotBlank()) name else persistedMaterial.name, + inventoryQuantity = if (inventoryQuantity != Float.MIN_VALUE) inventoryQuantity else persistedMaterial.inventoryQuantity, + isMixType = persistedMaterial.isMixType, + materialType = if (materialType != null) materialType!! else persistedMaterial.materialType!! + ) + }) + } +} diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialTypeService.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialTypeService.kt new file mode 100644 index 0000000..563f338 --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialTypeService.kt @@ -0,0 +1,100 @@ +package dev.fyloz.trial.colorrecipesexplorer.service + +import dev.fyloz.trial.colorrecipesexplorer.config.properties.MaterialTypeProperties +import dev.fyloz.trial.colorrecipesexplorer.exception.RestException +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsRestException +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialTypeSaveDto +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialTypeUpdateDto +import dev.fyloz.trial.colorrecipesexplorer.model.materialType +import dev.fyloz.trial.colorrecipesexplorer.repository.MaterialTypeRepository +import io.jsonwebtoken.lang.Assert +import org.springframework.http.HttpStatus +import org.springframework.stereotype.Service +import org.springframework.web.bind.annotation.ResponseStatus + +interface MaterialTypeService : NamedModelService { + /** Checks if a material type with the given [prefix] exists. */ + fun existsByPrefix(prefix: String): Boolean + + /** Checks if the given [materialType] is used by one or more materials. */ + fun isUsedByMaterial(materialType: MaterialType): Boolean + + /** Gets all system material types. */ + fun getAllSystemTypes(): Collection + + /** Gets all material types who are not a system type. */ + fun getAllNonSystemType(): Collection + + /** Saves and update the system material types. */ + fun saveSystemTypes(systemTypeProperties: Collection) +} + +@Service +class MaterialTypeServiceImpl(repository: MaterialTypeRepository, private val materialService: MaterialService) : + AbstractNamedModelService(repository), MaterialTypeService { + override fun existsByPrefix(prefix: String): Boolean = repository.existsByPrefix(prefix) + override fun isUsedByMaterial(materialType: MaterialType): Boolean = materialService.existsByMaterialType(materialType) + override fun getAllSystemTypes(): Collection = repository.findAllBySystemTypeIs(true) + override fun getAllNonSystemType(): Collection = repository.findAllBySystemTypeIs(false) + + override fun save(entity: MaterialType): MaterialType { + if (existsByPrefix(entity.prefix)) + throw EntityAlreadyExistsRestException(entity.prefix) + return super.save(entity) + } + + override fun update(entity: MaterialType): MaterialType { + Assert.notNull(entity.id, "MaterialTypeService.update() was called with a null identifier") + val persistedMaterialType = getById(entity.id!!) + with(repository.findByPrefix(entity.prefix)) { + if (this != null && id != entity.id) + throw EntityAlreadyExistsRestException(entity.prefix) + } + + return super.update(with(entity) { + MaterialType( + id = id, + name = if (name.isNotBlank()) name else persistedMaterialType.name, + prefix = if (prefix.isNotBlank()) prefix else persistedMaterialType.prefix + ) + }) + } + + override fun delete(entity: MaterialType) { + if (isUsedByMaterial(entity)) + throw CannotDeleteUsedMaterialTypeRestException() + + super.delete(entity) + } + + override fun saveSystemTypes(systemTypeProperties: Collection) { + val systemTypes = systemTypeProperties.map { it.toMaterialType() } + val oldSystemTypes = getAllSystemTypes().toMutableSet() + + fun saveOrUpdateSystemType(type: MaterialType) { + if (existsByName(type.name)) { + val persistedMaterialType = getByName(type.name) + update(materialType(type, newId = persistedMaterialType.id)) + } else { + save(type) + } + } + + // Save new system types + systemTypes.forEach { + saveOrUpdateSystemType(it) + oldSystemTypes.removeIf { c -> c.name == it.name } + } + + // Remove old system types + oldSystemTypes.forEach { update(materialType(it, newSystemType = false)) } + } +} + +@ResponseStatus(HttpStatus.CONFLICT) +class CannotDeleteUsedMaterialTypeRestException : RestException(HttpStatus.CONFLICT) { + override val exceptionMessage: String = "Cannot delete a used material type" + + override fun buildBody(): RestExceptionBody = object : RestExceptionBody() {} +} diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/Service.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/Service.kt new file mode 100644 index 0000000..b702ead --- /dev/null +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/Service.kt @@ -0,0 +1,123 @@ +package dev.fyloz.trial.colorrecipesexplorer.service + +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsRestException +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundRestException +import dev.fyloz.trial.colorrecipesexplorer.model.EntityDto +import dev.fyloz.trial.colorrecipesexplorer.model.Model +import dev.fyloz.trial.colorrecipesexplorer.model.NamedModel +import dev.fyloz.trial.colorrecipesexplorer.repository.NamedJpaRepository +import io.jsonwebtoken.lang.Assert +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.repository.findByIdOrNull + +/** + * A service implementing the basics CRUD operations. + * + * @param E The entity type + * @param S The entity save type + * @param U The entity update type + */ +interface Service, U : EntityDto, R : JpaRepository> { + val repository: R + + /** Gets all entities. */ + fun getAll(): Collection + + /** Saves a given [entity]. */ + fun save(entity: E): E + + /** Saves a given [entity]. */ + fun save(entity: S): E + + /** Updates a given [entity]. */ + fun update(entity: E): E + + /** Updates a given [entity]. */ + fun update(entity: U): E + + /** Deletes a given [entity]. */ + fun delete(entity: E) +} + +/** A service for entities implementing the [Model] interface. This service add supports for numeric identifiers. */ +interface ModelService, U : EntityDto, R : JpaRepository> : Service { + /** Checks if an entity with the given [id] exists. */ + fun existsById(id: Long): Boolean + + /** Gets the entity with the given [id]. */ + fun getById(id: Long): E + + /** Deletes the entity with the given [id]. */ + fun deleteById(id: Long) +} + +/** A service for entities implementing the [NamedModel] interface. This service add supports for name identifiers. */ +interface NamedModelService, U : EntityDto, R : JpaRepository> : ModelService { + /** Checks if an entity with the given [name] exists. */ + fun existsByName(name: String): Boolean + + /** Gets the entity with the given [name]. */ + fun getByName(name: String): E + + /** Deletes the entity with the given [name]. */ + fun deleteByName(name: String) +} + + +abstract class AbstractService, U : EntityDto, R : JpaRepository>(override val repository: R) : Service { + override fun getAll(): Collection = repository.findAll() + override fun save(entity: E): E = repository.save(entity) + override fun save(entity: S): E = save(entity.toEntity()) + override fun update(entity: E): E = repository.save(entity) + override fun update(entity: U): E = update(entity.toEntity()) + override fun delete(entity: E) = repository.delete(entity) +} + +abstract class AbstractModelService, U : EntityDto, R : JpaRepository>(repository: R) : + AbstractService(repository), ModelService { + override fun existsById(id: Long): Boolean = repository.existsById(id) + override fun getById(id: Long): E = repository.findByIdOrNull(id) ?: throw EntityNotFoundRestException(id) + + override fun save(entity: E): E { + if (entity.id != null && existsById(entity.id!!)) + throw EntityAlreadyExistsRestException(entity.id!!) + return super.save(entity) + } + + override fun update(entity: E): E { + Assert.notNull(entity.id, "AbstractModelService.update() was called with a null identifier") + if (!existsById(entity.id!!)) + throw EntityNotFoundRestException(entity.id!!) + return super.update(entity) + } + + override fun deleteById(id: Long) = repository.deleteById(id) +} + +abstract class AbstractNamedModelService, U : EntityDto, R : NamedJpaRepository>(repository: R) : + AbstractModelService(repository), NamedModelService { + override fun existsByName(name: String): Boolean = repository.existsByName(name) + override fun getByName(name: String): E = repository.findByName(name) ?: throw EntityNotFoundRestException(name) + override fun deleteByName(name: String) = repository.deleteByName(name) + + override fun save(entity: E): E { + if (existsByName(entity.name)) + throw EntityAlreadyExistsRestException(entity.name) + return super.save(entity) + } + + override fun update(entity: E): E { + Assert.notNull(entity.id, "AbstractNamedModelService.update() was called with a null identifier") + with(repository.findByName(entity.name)) { + if (this != null && id != entity.id) + throw EntityAlreadyExistsRestException(entity.name) + } + return super.update(entity) + } +} + +/** Transforms the given object to JSON. **/ +fun Any.asJson(): String { + return jacksonObjectMapper().writeValueAsString(this) +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f6205e7..5d02da7 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -20,13 +20,13 @@ cre.security.root.password=password cre.security.common.id=9998 cre.security.common.password=common # TYPES DE PRODUIT PAR DÉFAUT -entities.material-types.defaults[0].name=Aucun -entities.material-types.defaults[0].prefix= -entities.material-types.defaults[0].use-percentages=false -entities.material-types.defaults[1].name=Base -entities.material-types.defaults[1].prefix=BAS -entities.material-types.defaults[1].use-percentages=false -entities.material-types.base-name=Base +entities.material-types.systemTypes[0].name=Aucun +entities.material-types.systemTypes[0].prefix= +entities.material-types.systemTypes[0].usepercentages=false +entities.material-types.systemTypes[1].name=Base +entities.material-types.systemTypes[1].prefix=BAS +entities.material-types.systemTypes[1].usepercentages=false +entities.material-types.baseName=Base # DEBUG spring.jpa.show-sql=true spring.h2.console.enabled=true diff --git a/src/main/resources/junit-platform.properties b/src/main/resources/junit-platform.properties new file mode 100644 index 0000000..d265fd8 --- /dev/null +++ b/src/main/resources/junit-platform.properties @@ -0,0 +1 @@ +junit.jupiter.testinstance.lifecycle.default = per_class diff --git a/src/main/resources/thymeleaf/templates/recipe/explore.html b/src/main/resources/thymeleaf/templates/recipe/explore.html index 880407a..2ad6bd3 100644 --- a/src/main/resources/thymeleaf/templates/recipe/explore.html +++ b/src/main/resources/thymeleaf/templates/recipe/explore.html @@ -496,7 +496,7 @@ async function printMix(printButton) { const mixContainer = $(printButton).parents(".mixContainer"); - const allBases = $(mixContainer).find(".materialRow[data-materialtypename='[[${T(dev.fyloz.trial.colorrecipesexplorer.core.Preferences).baseMaterialTypeName}]]']"); + const allBases = $(mixContainer).find(".materialRow[data-materialtypename='[[${T(dev.fyloz.trial.colorrecipesexplorer.config.Preferences).baseMaterialTypeName}]]']"); console.log(allBases.length + " bases trouvées"); if (allBases.length <= 0) { showMessage(errorMsg, noBaseError); diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/AccountRepositoryTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/AccountRepositoryTest.kt new file mode 100644 index 0000000..0df1a7f --- /dev/null +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/AccountRepositoryTest.kt @@ -0,0 +1,101 @@ +package dev.fyloz.trial.colorrecipesexplorer.repository + +import dev.fyloz.trial.colorrecipesexplorer.model.EmployeeGroup +import dev.fyloz.trial.colorrecipesexplorer.model.employee +import dev.fyloz.trial.colorrecipesexplorer.model.employeeGroup +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager +import kotlin.test.* + +@DataJpaTest +class EmployeeRepositoryTest @Autowired constructor(private val employeeRepository: EmployeeRepository, val entityManager: TestEntityManager) { + private var employeeGroup = employeeGroup() + private val employee = employee(id = 0L, firstName = "fname", lastName = "lname") + private val anotherEmployee = employee(id = 1L, firstName = "another fname", lastName = "another lname") + private val groupEmployee = employee(id = 2L, firstName = "group fname", lastName = "group lname", group = employeeGroup) + private val defaultGroupEmployee = employee(id = 3L, firstName = "default fname", lastName = "default lname", group = employeeGroup, isDefaultGroupUser = true) + + @AfterEach + fun afterEach() { + if (employeeGroup.id != null) { + entityManager.remove(employeeGroup) + employeeGroup = employeeGroup(id = null) + groupEmployee.group = employeeGroup + defaultGroupEmployee.group = employeeGroup + } + } + + @Test + fun `existsByFirstNameAndLastName() returns true when an employee with the given first name and last name exists`() { + entityManager.persist(employee) + + val exists = employeeRepository.existsByFirstNameAndLastName(employee.firstName, employee.lastName) + + assertTrue(exists) + } + + @Test + fun `existsByFirstNameAndLastName() returns false when no employee with the given first name and last name exists`() { + entityManager.persist(anotherEmployee) + + val exists = employeeRepository.existsByFirstNameAndLastName(employee.firstName, employee.lastName) + + assertFalse(exists) + } + + @Test + fun `findByFirstNameAndLastName() returns the employee with the given first name and last name`() { + val expected = entityManager.persist(employee) + entityManager.persist(anotherEmployee) // Persist another employee to make sure the correct one is return by the tested method + assertNotNull(expected) + assertNotNull(expected.id) + + val found = employeeRepository.findByFirstNameAndLastName(employee.firstName, employee.lastName) + + assertEquals(found, expected) + } + + @Test + fun `findByFirstNameAndLastName() returns null when no employee with the given first name and last name exists`() { + entityManager.persist(anotherEmployee) + + val found = employeeRepository.findByFirstNameAndLastName(employee.firstName, employee.lastName) + + assertNull(found) + } + + @Test + fun `findAllByGroup() returns all employees in the given group`() { + entityManager.persist(employeeGroup) + entityManager.persist(employee) + entityManager.persist(groupEmployee) + entityManager.persist(defaultGroupEmployee) + + val found = employeeRepository.findAllByGroup(employeeGroup) + + assertTrue(found.contains(groupEmployee)) + assertTrue(found.contains(defaultGroupEmployee)) + assertFalse(found.contains(employee)) + } + + @Test + fun `findByIsDefaultGroupUserIsTrueAndGroupIs() returns the default employee of the given group`() { + entityManager.persist(employeeGroup) + entityManager.persist(employee) + entityManager.persist(groupEmployee) + entityManager.persist(defaultGroupEmployee) + + val found = employeeRepository.findByIsDefaultGroupUserIsTrueAndGroupIs(employeeGroup) + + assertEquals(found, defaultGroupEmployee) + } +} + +class EmployeeGroupRepositoryTest @Autowired constructor(employeeGroupRepository: EmployeeGroupRepository, entityManager: TestEntityManager) : + AbstractNamedJpaRepositoryTest(employeeGroupRepository, entityManager) { + override fun entity(name: String): EmployeeGroup = employeeGroup(name = name) +} + diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialRepositoryTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialRepositoryTest.kt new file mode 100644 index 0000000..27ee72a --- /dev/null +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialRepositoryTest.kt @@ -0,0 +1,60 @@ +package dev.fyloz.trial.colorrecipesexplorer.repository + +import dev.fyloz.trial.colorrecipesexplorer.model.Material +import dev.fyloz.trial.colorrecipesexplorer.model.material +import dev.fyloz.trial.colorrecipesexplorer.model.materialType +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class MaterialRepositoryTest @Autowired constructor(materialRepository: MaterialRepository, entityManager: TestEntityManager) : + AbstractNamedJpaRepositoryTest(materialRepository, entityManager) { + override fun entity(name: String): Material = material(name = name, materialType = null) + + @Test + fun `existsByMaterialType() returns true when a material with the given material type exists`() { + val materialType = materialType() + val material = material(materialType = materialType) + + entityManager.persist(materialType) + entityManager.persist(material) + + val found = repository.existsByMaterialType(materialType) + + assertTrue(found) + } + + @Test + fun `existsByMaterialType() returns false when no material with the given material type exists`() { + val materialType = materialType() + + entityManager.persist(materialType) + + val found = repository.existsByMaterialType(materialType) + + assertFalse(found) + } + + @Test + fun `findAllByMaterialType() returns all materials with the given material type`() { + val materialType = materialType(name = "material type", prefix = "MAT") + val anotherMaterialType = materialType(name = "another material type", prefix = "ANO") + val material = material(name = "material", materialType = materialType) + val anotherMaterial = material(name = "another material", materialType = materialType) + val yetAnotherMaterial = material(name = "yet another material", materialType = anotherMaterialType) + + entityManager.persist(materialType) + entityManager.persist(anotherMaterialType) + entityManager.persist(material) + entityManager.persist(anotherMaterial) + entityManager.persist(yetAnotherMaterial) + + val found = repository.findAllByMaterialType(materialType) + + assertTrue(found.contains(material)) + assertTrue(found.contains(anotherMaterial)) + assertFalse(found.contains(yetAnotherMaterial)) + } +} diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialTypeRepositoryTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialTypeRepositoryTest.kt new file mode 100644 index 0000000..2759ce9 --- /dev/null +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/MaterialTypeRepositoryTest.kt @@ -0,0 +1,89 @@ +package dev.fyloz.trial.colorrecipesexplorer.repository + +import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType +import dev.fyloz.trial.colorrecipesexplorer.model.materialType +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager +import org.junit.jupiter.api.Test +import kotlin.test.* + +class MaterialTypeRepositoryTest @Autowired constructor(materialTypeRepository: MaterialTypeRepository, entityManager: TestEntityManager) : + AbstractNamedJpaRepositoryTest(materialTypeRepository, entityManager) { + override fun entity(name: String): MaterialType = entity(name = name, prefix = "MAT") + private fun entity(name: String = "materialType", prefix: String = "MAT"): MaterialType = materialType(name = name, prefix = prefix) + + @Test + fun `existsByPrefix() returns true when a material type with the given prefix exists`() { + val materialType = entity() + entityManager.persist(materialType) + + val found = repository.existsByPrefix(materialType.prefix) + + assertTrue(found) + } + + @Test + fun `existsByPrefix() returns false when no material type with the given prefix exists`() { + val materialType = entity() + val anotherMaterialType = entity(prefix = "ANO") + entityManager.persist(anotherMaterialType) + + val found = repository.existsByPrefix(materialType.prefix) + + assertFalse(found) + } + + @Test + fun `findAllBySystemTypeIs() returns all system types`() { + val materialType = entity() + val systemType = materialType(name = "system type", prefix = "SYT", systemType = true) + val anotherSystemType = materialType(name = "another system type", prefix = "ASY", systemType = true) + + entityManager.persist(materialType) + entityManager.persist(systemType) + entityManager.persist(anotherSystemType) + + val found = repository.findAllBySystemTypeIs(true) + + assertTrue(found.contains(systemType)) + assertTrue(found.contains(anotherSystemType)) + assertFalse(found.contains(materialType)) + } + + @Test + fun `findAllBySystemTypeIs() returns all material types which are not system types`() { + val materialType = entity() + val anotherMaterialType = entity(name = "another material type", prefix = "AMT") + val systemType = materialType(name = "system type", prefix = "SYT", systemType = true) + + entityManager.persist(materialType) + entityManager.persist(anotherMaterialType) + entityManager.persist(systemType) + + val found = repository.findAllBySystemTypeIs(false) + + assertTrue(found.contains(anotherMaterialType)) + assertTrue(found.contains(materialType)) + assertFalse(found.contains(systemType)) + } + + @Test + fun `findByPrefix() returns the material type with the given prefix`() { + val materialType = entity() + entityManager.persist(materialType) + + val found = repository.findByPrefix(materialType.prefix) + + assertNotNull(found) + assertEquals(materialType, found) + } + + @Test + fun `findByPrefix() returns null when no material type with the given prefix exists`() { + entityManager.persist(entity(prefix = "ANO")) + + val found = repository.findByPrefix(entity().prefix) + + assertNull(found) + } +} diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/RepositoryTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/RepositoryTest.kt new file mode 100644 index 0000000..ea360fe --- /dev/null +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/repository/RepositoryTest.kt @@ -0,0 +1,65 @@ +package dev.fyloz.trial.colorrecipesexplorer.repository + +import dev.fyloz.trial.colorrecipesexplorer.model.NamedModel +import org.junit.jupiter.api.Test +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager +import kotlin.test.* + +@DataJpaTest +abstract class AbstractNamedJpaRepositoryTest>(protected val repository: R, protected val entityManager: TestEntityManager) { + protected abstract fun entity(name: String = "entity"): E + + @Test + fun `existsByName() returns true when an entity with the given name exists`() { + val entity = entity() + entityManager.persist(entity) + + val found = repository.existsByName(entity.name) + + assertTrue(found) + } + + @Test + fun `existsByName() returns false when no entity with the given name exist`() { + val entity = entity() + val anotherEntity = entity("another entity") + entityManager.persist(anotherEntity) + + val found = repository.existsByName(entity.name) + + assertFalse(found) + } + + @Test + fun `findByName() returns the entity with the given name`() { + val entity = entity() + entityManager.persist(entity) + + val found = repository.findByName(entity.name) + + assertNotNull(found) + assertEquals(entity.name, found.name) + } + + @Test + fun `findByName() returns null when no entity with the given name exists`() { + val entity = entity() + val anotherEntity = entity("another entity") + entityManager.persist(anotherEntity) + + val found = repository.findByName(entity.name) + + assertNull(found) + } + + @Test + fun `deleteByName() removes the entity with the given name`() { + val entity = entity() + entityManager.persist(entity) + + repository.deleteByName(entity.name) + + assertFalse(repository.existsByName(entity.name)) + } +} diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AbstractServiceTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AbstractServiceTest.kt new file mode 100644 index 0000000..a00d3f0 --- /dev/null +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AbstractServiceTest.kt @@ -0,0 +1,310 @@ +package dev.fyloz.trial.colorrecipesexplorer.service + +import com.nhaarman.mockitokotlin2.* +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsRestException +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundRestException +import dev.fyloz.trial.colorrecipesexplorer.model.EntityDto +import dev.fyloz.trial.colorrecipesexplorer.model.Model +import dev.fyloz.trial.colorrecipesexplorer.model.NamedModel +import dev.fyloz.trial.colorrecipesexplorer.repository.NamedJpaRepository +import org.junit.jupiter.api.* +import org.springframework.data.jpa.repository.JpaRepository +import java.util.* +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +abstract class AbstractServiceTest, U : EntityDto, S : Service, R : JpaRepository> { + protected abstract val repository: R + protected abstract val service: S + + protected abstract val entity: E + protected abstract val anotherEntity: E + protected abstract val entitySaveDto: N + protected abstract val entityUpdateDto: U + + protected val entityList: List + get() = listOf( + entity, + anotherEntity + ) + + @AfterEach + open fun afterEach() { + reset(repository, service, entitySaveDto, entityUpdateDto) + } + + @Nested + inner class GetAll { + @Test + fun `returns all available entities`() { + whenever(repository.findAll()).doReturn(entityList) + + val found = service.getAll() + + assertEquals(entityList, found) + } + + @Test + fun `returns empty list when there is no entities`() { + whenever(repository.findAll()).doReturn(listOf()) + + val found = service.getAll() + + assertTrue { found.isEmpty() } + } + } + + @Nested + inner class Save { + @Test + fun `calls and returns save() in the repository`() { + whenever(repository.save(entity)).doReturn(entity) + + val found = service.save(entity) + + verify(repository).save(entity) + assertEquals(entity, found) + } + } + + @Nested + inner class SaveDto { + @Test + fun `calls and returns save() with the created entity`() { + doReturn(entity).whenever(service).save(entity) + doReturn(entity).whenever(entitySaveDto).toEntity() + + val found = service.save(entitySaveDto) + + verify(service).save(entity) + assertEquals(entity, found) + } + } + + @Nested + inner class Update { + @Test + fun `calls and returns save() in the repository`() { + whenever(repository.save(entity)).doReturn(entity) + + val found = service.update(entity) + + verify(repository).save(entity) + assertEquals(entity, found) + } + } + + @Nested + inner class UpdateDto { + @Test + fun `calls and returns update() with the created entity`() { + doReturn(entity).whenever(service).update(entity) + doReturn(entity).whenever(entityUpdateDto).toEntity() + + val found = service.update(entityUpdateDto) + + verify(service).update(entity) + assertEquals(entity, found) + } + } + + @Nested + inner class Delete { + @Test + fun `calls delete() in the repository`() { + service.delete(entity) + + verify(repository).delete(entity) + } + } +} + +abstract class AbstractModelServiceTest, U : EntityDto, S : ModelService, R : JpaRepository> : AbstractServiceTest() { + @Nested + inner class ExistsById { + @Test + fun `returns true when an entity with the given id exists in the repository`() { + whenever(repository.existsById(entity.id!!)).doReturn(true) + + val found = service.existsById(entity.id!!) + + assertTrue(found) + } + + @Test + fun `returns false when no entity with the given id exists in the repository`() { + whenever(repository.existsById(entity.id!!)).doReturn(false) + + val found = service.existsById(entity.id!!) + + assertFalse(found) + } + } + + @Nested + inner class GetById { + @Test + fun `returns the entity with the given id from the repository`() { + whenever(repository.findById(entity.id!!)).doReturn(Optional.of(entity)) + + val found = service.getById(entity.id!!) + + assertEquals(entity, found) + } + + @Test + fun `throws EntityNotFoundRestException when no entity with the given id exists in the repository`() { + whenever(repository.findById(entity.id!!)).doReturn(Optional.empty()) + + val exception = assertThrows { service.getById(entity.id!!) } + assertTrue(exception.value is Long) + assertEquals(entity.id, exception.value as Long) + } + } + + @Nested + inner class SaveModel { + @Test + fun `throws EntityAlreadyExistsRestException when an entity with the given id exists in the repository`() { + doReturn(true).whenever(repository).existsById(entity.id!!) + + val exception = assertThrows { service.save(entity) } + assertTrue(exception.value is Long) + assertEquals(entity.id, exception.value as Long) + } + } + + @Nested + inner class Update { + @Test + fun `calls and returns save() in the repository`() { + whenever(repository.save(entity)).doReturn(entity) + doReturn(true).whenever(service).existsById(entity.id!!) + doReturn(entity).whenever(service).getById(entity.id!!) + + val found = service.update(entity) + + verify(repository).save(entity) + assertEquals(entity, found) + } + + @Test + fun `throws EntityNotFoundRestException when no entity with the given id exists in the repository`() { + doReturn(false).whenever(service).existsById(entity.id!!) + + val exception = assertThrows { service.update(entity) } + assertTrue(exception.value is Long) + assertEquals(entity.id, exception.value as Long) + } + } + + @Nested + inner class DeleteById { + @Test + fun `calls deleteById() in the repository with the given id`() { + service.deleteById(entity.id!!) + + verify(repository).deleteById(entity.id!!) + } + } +} + +abstract class AbstractNamedModelServiceTest, U : EntityDto, S : NamedModelService, R : NamedJpaRepository> : AbstractModelServiceTest() { + protected abstract val entityWithEntityName: E + + @Nested + inner class ExistsByName { + @Test + fun `returns true when an entity with the given name exists`() { + whenever(repository.existsByName(entity.name)).doReturn(true) + + val found = service.existsByName(entity.name) + + assertTrue(found) + } + + @Test + fun `returns false when no entity with the given name exists`() { + whenever(repository.existsByName(entity.name)).doReturn(false) + + val found = service.existsByName(entity.name) + + assertFalse(found) + } + } + + @Nested + inner class GetByName { + @Test + fun `returns the entity with the given name`() { + whenever(repository.findByName(entity.name)).doReturn(entity) + + val found = service.getByName(entity.name) + + assertEquals(entity, found) + } + + @Test + fun `throws EntityNotFoundRestException when no entity with the given name exists`() { + whenever(repository.findByName(entity.name)).doReturn(null) + + val exception = assertThrows { service.getByName(entity.name) } + assertEquals(entity.name, exception.value) + } + } + + @Nested + inner class SaveNamedModel { + @Test + fun `throws EntityAlreadyExistsRestException when an entity with the given name exists`() { + doReturn(true).whenever(service).existsByName(entity.name) + + val exception = assertThrows { service.save(entity) } + assertEquals(entity.name, exception.value) + } + } + + @Nested + inner class Update { + @Test + fun `calls and returns save() in the repository`() { + whenever(repository.save(entity)).doReturn(entity) + whenever(repository.findByName(entity.name)).doReturn(null) + doReturn(true).whenever(service).existsById(entity.id!!) + + val found = service.update(entity) + + verify(repository).save(entity) + assertEquals(entity, found) + } + + @Test + fun `throws EntityNotFoundRestException when no entity with the given id exists in the repository`() { + whenever(repository.findByName(entity.name)).doReturn(null) + doReturn(false).whenever(service).existsById(entity.id!!) + + val exception = assertThrows { service.update(entity) } + assertTrue(exception.value is Long) + assertEquals(entity.id, exception.value as Long) + } + + @Test + fun `throws EntityAlreadyExistsRestException when an entity with the updated name exists`() { + whenever(repository.findByName(entity.name)).doReturn(entityWithEntityName) + + val exception = assertThrows { service.update(entity) } + assertEquals(entity.name, exception.value) + } + } + + @Nested + inner class DeleteByName { + @Test + fun `calls deleteByName() in the repository with the given name`() { + service.deleteByName(entity.name) + + verify(repository).deleteByName(entity.name) + } + } +} diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AccountsServiceTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AccountsServiceTest.kt new file mode 100644 index 0000000..29b29ab --- /dev/null +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/AccountsServiceTest.kt @@ -0,0 +1,447 @@ +package dev.fyloz.trial.colorrecipesexplorer.service + +import com.nhaarman.mockitokotlin2.* +import dev.fyloz.trial.colorrecipesexplorer.config.SecurityConfigurationProperties +import dev.fyloz.trial.colorrecipesexplorer.config.defaultGroupCookieName +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsRestException +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundRestException +import dev.fyloz.trial.colorrecipesexplorer.model.* +import dev.fyloz.trial.colorrecipesexplorer.repository.EmployeeGroupRepository +import dev.fyloz.trial.colorrecipesexplorer.repository.EmployeeRepository +import org.junit.jupiter.api.* +import org.junit.jupiter.api.Test +import org.springframework.mock.web.MockHttpServletResponse +import org.springframework.security.core.userdetails.User +import org.springframework.security.core.userdetails.UsernameNotFoundException +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder +import java.util.* +import javax.servlet.http.Cookie +import javax.servlet.http.HttpServletRequest +import kotlin.test.* + +class EmployeeServiceTest : AbstractModelServiceTest() { + private val passwordEncoder = BCryptPasswordEncoder() + + override val entity: Employee = employee(passwordEncoder, id = 0L) + override val anotherEntity: Employee = employee(passwordEncoder, id = 1L) + private val entityDefaultGroupUser = employee(passwordEncoder, id = 2L, isDefaultGroupUser = true) + private val entitySystemUser = employee(passwordEncoder, id = 3L, isSystemUser = true) + private val group = employeeGroup(id = 0L) + override val entitySaveDto: EmployeeSaveDto = spy(employeeSaveDto(passwordEncoder, id = 0L)) + override val entityUpdateDto: EmployeeUpdateDto = spy(employeeUpdateDto(id = 0L)) + + override val repository: EmployeeRepository = mock() + override val service: EmployeeService = spy(EmployeeServiceImpl(repository, passwordEncoder)) + + private val entitySaveDtoEmployee = Employee(entitySaveDto.id, entitySaveDto.firstName, entitySaveDto.lastName, passwordEncoder.encode(entitySaveDto.password), isDefaultGroupUser = false, isSystemUser = false, group = null, permissions = entitySaveDto.permissions) + + @AfterEach + override fun afterEach() { + reset(entitySaveDto, entityUpdateDto) + super.afterEach() + } + + @Nested + inner class ExistsByFirstNameAndLastName { + @Test + fun `returns true when an employee with the given first name and last name exists`() { + whenever(repository.existsByFirstNameAndLastName(entity.firstName, entity.lastName)).doReturn(true) + + val found = service.existsByFirstNameAndLastName(entity.firstName, entity.lastName) + + assertTrue(found) + } + + @Test + fun `returns false when no employee with the given first name and last name exists`() { + whenever(repository.existsByFirstNameAndLastName(entity.firstName, entity.lastName)).doReturn(false) + + val found = service.existsByFirstNameAndLastName(entity.firstName, entity.lastName) + + assertFalse(found) + } + } + + @Nested + inner class GetById { + @Test + fun `throws EntityNotFoundRestException when the corresponding employee is a default group user`() { + whenever(repository.findById(entityDefaultGroupUser.id)).doReturn(Optional.of(entityDefaultGroupUser)) + + val exception = assertThrows { service.getById(entityDefaultGroupUser.id, ignoreDefaultGroupUsers = true, ignoreSystemUsers = false) } + assertTrue(exception.value is Long) + assertEquals(entityDefaultGroupUser.id, exception.value as Long) + } + + @Test + fun `throws EntityNotFoundRestException when the corresponding employee is a system user`() { + whenever(repository.findById(entitySystemUser.id)).doReturn(Optional.of(entitySystemUser)) + + val exception = assertThrows { service.getById(entitySystemUser.id, ignoreDefaultGroupUsers = false, ignoreSystemUsers = true) } + assertTrue(exception.value is Long) + assertEquals(entitySystemUser.id, exception.value as Long) + } + } + + @Nested + inner class GetByGroup { + @Test + fun `returns all the employees with the given group from the repository`() { + whenever(repository.findAllByGroup(group)).doReturn(entityList) + + val found = service.getByGroup(group) + + assertTrue(found.containsAll(entityList)) + assertTrue(entityList.containsAll(found)) + } + + @Test + fun `returns an empty list when there is no employee with the given group in the repository`() { + whenever(repository.findAllByGroup(group)).doReturn(listOf()) + + val found = service.getByGroup(group) + + assertTrue(found.isEmpty()) + } + } + + @Nested + inner class GetDefaultGroupUser { + @Test + fun `returns the default employee of the given group from the repository`() { + whenever(repository.findByIsDefaultGroupUserIsTrueAndGroupIs(group)).doReturn(entityDefaultGroupUser) + + val found = service.getDefaultGroupEmployee(group) + + assertEquals(entityDefaultGroupUser, found) + } + } + + @Nested + inner class Save { + @Test + fun `calls save() in the repository`() { + whenever(repository.save(entity)).doReturn(entity) + doReturn(false).whenever(repository).existsByFirstNameAndLastName(entity.firstName, entity.lastName) + + val found = service.save(entity) + + verify(repository).save(entity) + assertEquals(entity, found) + } + + @Test + fun `throws EntityAlreadyExistsException when firstName and lastName exists`() { + doReturn(true).whenever(repository).existsByFirstNameAndLastName(entity.firstName, entity.lastName) + + val exception = assertThrows { service.save(entity) } + assertEquals("${entity.firstName} ${entity.lastName}", exception.value) + } + } + + @Nested + inner class SaveDto { + @Test + fun `calls save() with the created employee`() { + whenever(entitySaveDto.toEntity()).doReturn(entitySaveDtoEmployee) + doReturn(entitySaveDtoEmployee).whenever(service).save(entitySaveDtoEmployee) + + val found = service.save(entitySaveDto) + + verify(service).save(entitySaveDtoEmployee) + assertEquals(entitySaveDtoEmployee, found) + } + } + + @Nested + inner class Update { + @Test + fun `throws EntityAlreadyExistsRestException when a different employee with the given first name and last name exists`() { + whenever(repository.findByFirstNameAndLastName(entity.firstName, entity.lastName)).doReturn(entityDefaultGroupUser) + doReturn(entity).whenever(service).getById(eq(entity.id), any(), any()) + + val exception = assertThrows { service.update(entity, true, ignoreSystemUsers = true) } + assertTrue(exception.value is String) + assertEquals("${entity.firstName} ${entity.lastName}", exception.value as String) + } + } +} + +class EmployeeGroupServiceTest : AbstractModelServiceTest() { + private val employeeService: EmployeeService = mock() + override val repository: EmployeeGroupRepository = mock() + override val service: EmployeeGroupServiceImpl = spy(EmployeeGroupServiceImpl(repository, employeeService)) + + override val entity: EmployeeGroup = employeeGroup(id = 0L, name = "group") + override val anotherEntity: EmployeeGroup = employeeGroup(id = 1L, name = "another group") + override val entitySaveDto: EmployeeGroupSaveDto = spy(employeeGroupSaveDto(name = "group")) + override val entityUpdateDto: EmployeeGroupUpdateDto = spy(employeeGroupUpdateDto(id = 0L, name = "groupL")) + + private val groupEmployeeId = 1000000L + entity.id!! + private val groupEmployee = employee(BCryptPasswordEncoder(), id = groupEmployeeId, group = entity) + + @BeforeEach + override fun afterEach() { + reset(employeeService, entitySaveDto, entityUpdateDto) + super.afterEach() + } + + @Nested + inner class ExistsByName { + @Test + fun `returns true when a group with the given name exists in the repository`() { + whenever(repository.existsByName(entity.name)).doReturn(true) + + val found = service.existsByName(entity.name) + + assertTrue(found) + } + + @Test + fun `returns false when no group with the given name exists in the repository`() { + whenever(repository.existsByName(entity.name)).doReturn(false) + + val found = service.existsByName(entity.name) + + assertFalse(found) + } + } + + @Nested + inner class GetEmployeesForGroup { + @Test + fun `returns all employees in the given group`() { + val group = employeeGroup(id = 1L, employees = mutableSetOf(groupEmployee)) + + doReturn(group).whenever(service).getById(group.id!!) + + val found = service.getEmployeesForGroup(group.id!!) + + assertTrue(found.contains(groupEmployee)) + assertTrue(found.size == 1) + } + + @Test + fun `returns empty collection when the given group contains any employee`() { + doReturn(entity).whenever(service).getById(entity.id!!) + + val found = service.getEmployeesForGroup(entity.id!!) + + assertTrue(found.isEmpty()) + } + } + + @Nested + inner class GetRequestDefaultGroup { + @Test + fun `returns the group contained in the cookie of the HTTP request`() { + val cookies: Array = arrayOf(Cookie(defaultGroupCookieName, groupEmployeeId.toString())) + val request: HttpServletRequest = mock() + + whenever(request.cookies).doReturn(cookies) + whenever(employeeService.getById(eq(groupEmployeeId), any(), any())).doReturn(groupEmployee) + + val found = service.getRequestDefaultGroup(request) + + assertEquals(entity, found) + } + + @Test + fun `throws EntityNotFoundRestException when the HTTP request does not contains a cookie for the default group`() { + val request: HttpServletRequest = mock() + + whenever(request.cookies).doReturn(arrayOf()) + + val exception = assertThrows { service.getRequestDefaultGroup(request) } + assertEquals("defaultGroup", exception.value) + } + } + + @Nested + inner class SetResponseDefaultGroup { + @Test + fun `the default group cookie has been added to the given HTTP response with the given group id`() { + val response = MockHttpServletResponse() + + whenever(employeeService.getDefaultGroupEmployee(entity)).doReturn(groupEmployee) + doReturn(entity).whenever(service).getById(entity.id!!) + + service.setResponseDefaultGroup(entity.id!!, response) + val found = response.getCookie(defaultGroupCookieName) + + assertNotNull(found) + assertEquals(defaultGroupCookieName, found.name) + assertEquals(groupEmployeeId.toString(), found.value) + assertEquals(defaultGroupCookieMaxAge, found.maxAge) + assertTrue(found.isHttpOnly) + assertTrue(found.secure) + } + } + + @Nested + inner class AddEmployeeToGroup { + @Test + fun `calls addEmployeeToGroup() with the group of the given groupId and the employee of the given employeeId`() { + whenever(employeeService.getById(groupEmployeeId)).doReturn(groupEmployee) + doReturn(entity).whenever(service).getById(entity.id!!) + + service.addEmployeeToGroup(entity.id!!, groupEmployeeId) + + verify(service).addEmployeeToGroup(entity, groupEmployee) + } + + @Test + fun `calls update() and employeeService_update() with the updated entities`() { + val group = employeeGroup() + val employee = employee() + + whenever(employeeService.update(employee)).doReturn(employee) + doReturn(group).whenever(service).update(group) + + service.addEmployeeToGroup(group, employee) + + verify(service).update(group) + verify(employeeService).update(employee) + + assertTrue(group.employees.contains(employee)) + assertEquals(group, employee.group) + } + + @Test + fun `do nothing when the given employee is already in the given group`() { + val group = employeeGroup() + val employee = employee(group = group) + + service.addEmployeeToGroup(group, employee) + + verify(service, times(0)).update(group) + verify(employeeService, times(0)).update(employee) + } + + @Test + fun `remove previous group from the given employee and add it the the given group`() { + val group = employeeGroup(id = 0L) + val previousGroup = employeeGroup(id = 1L) + val employee = employee(group = previousGroup) + + whenever(employeeService.update(employee)).doReturn(employee) + doReturn(group).whenever(service).update(group) + doReturn(group).whenever(service).update(previousGroup) + + service.addEmployeeToGroup(group, employee) + + verify(service).removeEmployeeFromGroup(previousGroup, employee) + verify(service).update(group) + verify(employeeService, times(2)).update(employee) + + assertTrue(group.employees.contains(employee)) + assertEquals(group, employee.group) + } + } + + @Nested + inner class RemoveEmployeeFromGroup { + @Test + fun `calls removeEmployeeFromGroup() with the group of the given group id and the employee of the given employee id`() { + whenever(employeeService.getById(groupEmployeeId)).doReturn(groupEmployee) + doReturn(entity).whenever(service).getById(entity.id!!) + doAnswer { it.arguments[0] }.whenever(service).update(any()) + + service.removeEmployeeFromGroup(entity.id!!, groupEmployeeId) + + verify(service).removeEmployeeFromGroup(entity, groupEmployee) + } + + @Test + fun `calls update() and employeeService_update() with the updated entities`() { + val employee = employee() + val group = employeeGroup(employees = mutableSetOf(employee)) + employee.group = group + + whenever(employeeService.update(employee)).doReturn(employee) + doReturn(group).whenever(service).update(group) + + service.removeEmployeeFromGroup(group, employee) + + verify(service).update(group) + verify(employeeService).update(employee) + + assertFalse(group.employees.contains(employee)) + assertNull(employee.group) + } + + @Test + fun `do nothing when the given employee is not in the given group`() { + val employee = employee() + val group = employeeGroup(id = 0L) + val anotherGroup = employeeGroup(id = 1L, employees = mutableSetOf(employee)) + employee.group = anotherGroup + + service.removeEmployeeFromGroup(group, employee) + + verify(service, times(0)).update(anotherGroup) + verify(employeeService, times(0)).update(employee) + } + + @Test + fun `do nothing when the given employee is not in a group`() { + val employee = employee() + val group = employeeGroup() + + service.removeEmployeeFromGroup(group, employee) + + verify(service, times(0)).update(group) + verify(employeeService, times(0)).update(employee) + } + } +} + +class EmployeeUserDetailsServiceTest { + private val employeeService: EmployeeService = mock() + private val securityConfigurationProperties = SecurityConfigurationProperties().apply { + jwtSecret = "secret" + jwtDuration = 1000L + root = SecurityConfigurationProperties.SystemUserCredentials(999L, "root") + } + private val service = spy(EmployeeUserDetailsServiceImpl(employeeService, securityConfigurationProperties)) + + private val employee = employee(id = 0L) + + @BeforeEach + fun beforeEach() { + reset(employeeService, service) + } + + @Nested + inner class LoadUserByUsername { + @Test + fun `calls loadUserByEmployeeId() with the given username as an id`() { + whenever(employeeService.getById(eq(employee.id), any(), any())).doReturn(employee) + doReturn(User(employee.id.toString(), employee.password, listOf())).whenever(service).loadUserByEmployeeId(employee.id) + + service.loadUserByUsername(employee.id.toString()) + + verify(service).loadUserByEmployeeId(eq(employee.id), any()) + } + + @Test + fun `throws UsernameNotFoundException when no employee with the given id exists`() { + whenever(employeeService.getById(eq(employee.id), any(), any())).doThrow(EntityNotFoundRestException(employee.id)) + + assertThrows { service.loadUserByUsername(employee.id.toString()) } + } + } + + @Nested + inner class LoadUserByEmployeeId { + @Test + fun `returns an User corresponding to the employee with the given id`() { + whenever(employeeService.getById(eq(employee.id), any(), any())).doReturn(employee) + + val found = service.loadUserByEmployeeId(employee.id) + + assertEquals(employee.id, found.username.toLong()) + assertEquals(employee.password, found.password) + } + } +} diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialServiceTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialServiceTest.kt new file mode 100644 index 0000000..4ba889d --- /dev/null +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialServiceTest.kt @@ -0,0 +1,154 @@ +package dev.fyloz.trial.colorrecipesexplorer.service + +import com.nhaarman.mockitokotlin2.* +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsRestException +import dev.fyloz.trial.colorrecipesexplorer.model.* +import dev.fyloz.trial.colorrecipesexplorer.repository.MaterialRepository +import dev.fyloz.trial.colorrecipesexplorer.service.files.SimdutService +import dev.fyloz.trial.colorrecipesexplorer.service.model.MixQuantityService +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.springframework.mock.web.MockMultipartFile +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class MaterialServiceTest : AbstractNamedModelServiceTest() { + private val mixQuantityService: MixQuantityService = mock() + private val simdutService: SimdutService = mock() + override val repository: MaterialRepository = mock() + override val service: MaterialService = spy(MaterialServiceImpl(repository, mixQuantityService, simdutService)) + + override val entity: Material = material(id = 0L, name = "material") + override val anotherEntity: Material = material(id = 1L, name = "another material") + override val entityWithEntityName: Material = material(id = 2L, name = "material") + override val entitySaveDto: MaterialSaveDto = spy(materialSaveDto()) + override val entityUpdateDto: MaterialUpdateDto = spy(materialUpdateDto(id = 0L)) + + @AfterEach + override fun afterEach() { + reset(mixQuantityService, simdutService, entitySaveDto, entityUpdateDto) + super.afterEach() + } + + @Nested + inner class ExistsByMaterialType { + private val materialType = materialType() + + @Test + fun `returns true when a material with the given material type exists in the repository`() { + whenever(repository.existsByMaterialType(materialType)).doReturn(true) + + val found = service.existsByMaterialType(materialType) + + assertTrue(found) + } + + @Test + fun `returns false when no material with the given material type exists in the repository`() { + whenever(repository.existsByMaterialType(materialType)).doReturn(false) + + val found = service.existsByMaterialType(materialType) + + assertFalse(found) + } + } + + @Nested + inner class IsLinkedToMixes { + @Test + fun `returns true when a mix contains the given material in the repository`() { + whenever(mixQuantityService.existsByMaterial(entity)).doReturn(true) + + val found = service.isLinkedToMixes(entity) + + assertTrue(found) + } + + @Test + fun `returns false when no mix contains the given material in the repository`() { + whenever(mixQuantityService.existsByMaterial(entity)).doReturn(false) + + val found = service.isLinkedToMixes(entity) + + assertFalse(found) + } + } + + @Nested + inner class GetAllNotMixType { + @Test + fun `returns a list containing every material that are not a mix type`() { + val mixTypeMaterial = material(name = "mix type material", isMixType = true) + val materialList = listOf(entity, mixTypeMaterial) + + doReturn(materialList).whenever(service).getAll() + + val found = service.getAllNotMixType() + + assertTrue(found.contains(entity)) + assertFalse(found.contains(mixTypeMaterial)) + } + } + + @Nested + inner class Save { + @Test + fun `throws EntityAlreadyExistsRestException when a material with the given name exists in the repository`() { + doReturn(true).whenever(service).existsByName(entity.name) + + val exception = assertThrows { service.save(entity) } + assertEquals(entity.name, exception.value) + } + } + + @Nested + inner class SaveDto { + @Test + fun `calls simdutService_write() with the saved entity`() { + val mockMultipartFile = spy(MockMultipartFile("simdut", byteArrayOf())) + val materialSaveDto = spy(materialSaveDto(simdutFile = mockMultipartFile)) + + doReturn(false).whenever(mockMultipartFile).isEmpty + doReturn(entity).whenever(materialSaveDto).toEntity() + doReturn(entity).whenever(service).save(entity) + + service.save(materialSaveDto) + + verify(simdutService).write(entity, mockMultipartFile) + } + } + + @Nested + inner class Update { + @Test + fun `throws EntityAlreadyExistsRestException when another material with the updated name exists in the repository`() { + val material = material(id = 0L, name = "name") + val anotherMaterial = material(id = 1L, name = "name") + + whenever(repository.findByName(material.name)).doReturn(anotherMaterial) + doReturn(entity).whenever(service).getById(material.id!!) + + val exception = assertThrows { service.update(material) } + assertEquals(material.name, exception.value) + } + } + + @Nested + inner class UpdateDto { + @Test + fun `calls simdutService_update() with the updated entity`() { + val mockSimdutFile = MockMultipartFile("simdut", byteArrayOf()) + val materialUpdateDto = spy(materialUpdateDto(id = 0L, simdutFile = mockSimdutFile)) + + doReturn(entity).whenever(service).update(entity) + doReturn(entity).whenever(materialUpdateDto).toEntity() + + service.update(materialUpdateDto) + + verify(simdutService).update(mockSimdutFile, entity) + } + } +} diff --git a/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialTypeServiceTest.kt b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialTypeServiceTest.kt new file mode 100644 index 0000000..62f2827 --- /dev/null +++ b/src/test/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/MaterialTypeServiceTest.kt @@ -0,0 +1,181 @@ +package dev.fyloz.trial.colorrecipesexplorer.service + +import com.nhaarman.mockitokotlin2.* +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsRestException +import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundRestException +import dev.fyloz.trial.colorrecipesexplorer.model.* +import dev.fyloz.trial.colorrecipesexplorer.repository.MaterialTypeRepository +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class MaterialTypeServiceTest : AbstractNamedModelServiceTest() { + override val repository: MaterialTypeRepository = mock() + private val materialService: MaterialService = mock() + override val service: MaterialTypeService = spy(MaterialTypeServiceImpl(repository, materialService)) + 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 entityWithEntityName: MaterialType = materialType(2L, name = entity.name, prefix = "EEN") + 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) + override val entitySaveDto: MaterialTypeSaveDto = spy(materialTypeSaveDto(name = "material type", prefix = "MAT")) + override val entityUpdateDto: MaterialTypeUpdateDto = spy(materialTypeUpdateDto(id = 0L, name = "material type", prefix = "MAT")) + + @AfterEach + override fun afterEach() { + reset(materialService) + super.afterEach() + } + + @Nested + inner class ExistsByPrefix { + @Test + fun `returns true when a material type with the given prefix exists`() { + whenever(repository.existsByPrefix(entity.prefix)).doReturn(true) + + val found = service.existsByPrefix(entity.prefix) + + assertTrue(found) + } + + @Test + fun `returns false when no material type with the given prefix exists`() { + whenever(repository.existsByPrefix(entity.prefix)).doReturn(false) + + val found = service.existsByPrefix(entity.prefix) + + assertFalse(found) + } + } + + @Nested + inner class IsUsedByMaterial { + @Test + fun `returns true when materialService_existsByMaterialType() returns true`() { + whenever(materialService.existsByMaterialType(entity)).doReturn(true) + + val found = service.isUsedByMaterial(entity) + + assertTrue(found) + } + + @Test + fun `returns false when materialService_existsByMaterialType() returns false`() { + whenever(materialService.existsByMaterialType(entity)).doReturn(false) + + val found = service.isUsedByMaterial(entity) + + assertFalse(found) + } + } + + @Nested + inner class GetAllSystemTypes { + @Test + fun `returns all system types`() { + whenever(repository.findAllBySystemTypeIs(true)).doReturn(listOf(systemType, anotherSystemType)) + + val found = service.getAllSystemTypes() + + assertTrue(found.contains(systemType)) + assertTrue(found.contains(anotherSystemType)) + } + } + + @Nested + inner class GetAllNonSystemTypes { + @Test + fun `returns all non system types`() { + whenever(repository.findAllBySystemTypeIs(false)).doReturn(listOf(entity, anotherEntity)) + + val found = service.getAllNonSystemType() + + assertTrue(found.contains(entity)) + assertTrue(found.contains(anotherEntity)) + } + } + + @Nested + inner class SaveMaterialType { + @Test + fun `throws EntityAlreadyExistsRestException when a material type with the given prefix already exists`() { + doReturn(true).whenever(service).existsByPrefix(entity.prefix) + + val exception = assertThrows { service.save(entity) } + assertEquals(entity.prefix, exception.value) + } + } + + @Nested + inner class Update { + @Test + fun `calls and returns save() in the repository`() { + whenever(repository.save(entity)).doReturn(entity) + whenever(repository.findByName(entity.name)).doReturn(null) + whenever(repository.findByPrefix(entity.prefix)).doReturn(null) + doReturn(true).whenever(service).existsById(entity.id!!) + doReturn(entity).whenever(service).getById(entity.id!!) + + val found = service.update(entity) + + verify(repository).save(entity) + assertEquals(entity, found) + } + + @Test + fun `throws EntityNotFoundRestException when no entity with the given id exists in the repository`() { + whenever(repository.findByName(entity.name)).doReturn(null) + whenever(repository.findByPrefix(entity.prefix)).doReturn(null) + doReturn(false).whenever(service).existsById(entity.id!!) + doReturn(null).whenever(service).getById(entity.id!!) + + val exception = assertThrows { service.update(entity) } + assertTrue(exception.value is Long) + assertEquals(entity.id, exception.value as Long) + } + + @Test + fun `throws EntityAlreadyExistsRestException when an entity with the updated name exists`() { + whenever(repository.findByName(entity.name)).doReturn(entityWithEntityName) + whenever(repository.findByPrefix(entity.prefix)).doReturn(null) + doReturn(true).whenever(service).existsById(entity.id!!) + doReturn(entity).whenever(service).getById(entity.id!!) + + val exception = assertThrows { service.update(entity) } + assertEquals(entity.name, exception.value) + } + + @Test + fun `throws EntityAlreadyExistsRestException when an entity with the updated prefix exists`() { + val anotherMaterialType = materialType(prefix = entity.prefix) + whenever(repository.findByPrefix(entity.prefix)).doReturn(anotherMaterialType) + doReturn(entity).whenever(service).getById(entity.id!!) + + val exception = assertThrows { service.update(entity) } + assertEquals(entity.prefix, exception.value) + } + } + + @Nested + inner class Delete { + @Test + fun `calls delete() in the repository`() { + doReturn(false).whenever(service).isUsedByMaterial(entity) + + service.delete(entity) + + verify(repository).delete(entity) + } + + @Test + fun `throws CannotDeleteUsedMaterialTypeRestException when the material type is in use`() { + doReturn(true).whenever(service).isUsedByMaterial(entity) + + assertThrows { service.delete(entity) } + } + } +} diff --git a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplicationTest.java b/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplicationTest.java deleted file mode 100644 index ffa8bf7..0000000 --- a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplicationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -@SpringBootTest -public class ColorRecipesExplorerApplicationTest { - - @Test - public void contextLoads() { - } - -} diff --git a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/CompanyBuilder.java b/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/CompanyBuilder.java deleted file mode 100644 index 47a1d97..0000000 --- a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/CompanyBuilder.java +++ /dev/null @@ -1,23 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.builders; - -import dev.fyloz.trial.colorrecipesexplorer.core.model.Company; - -public class CompanyBuilder { - - private Long id = 0L; - private String name = "Trial"; - - public CompanyBuilder id(Long val) { - id = val; - return this; - } - - public CompanyBuilder name(String val) { - name = val; - return this; - } - - public Company build() { - return new Company(id, name); - } -} diff --git a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/MaterialBuilder.java b/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/MaterialBuilder.java deleted file mode 100644 index 28d7cc0..0000000 --- a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/MaterialBuilder.java +++ /dev/null @@ -1,50 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.builders; - -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; - -public class MaterialBuilder { - - private Long id = 0L; - private String name = "DEDEL"; - private Float inventoryQuantity = 50000.00f; - private boolean isMixType = false; - private MaterialType materialType = new MaterialTypeBuilder().build(); - - public MaterialBuilder() { - } - - public MaterialBuilder id(Long id) { - this.id = id; - - return this; - } - - public MaterialBuilder name(String name) { - this.name = name; - - return this; - } - - public MaterialBuilder inventoryQuantity(Float inventoryQuantity) { - this.inventoryQuantity = inventoryQuantity; - - return this; - } - - public MaterialBuilder mixType(boolean mixType) { - isMixType = mixType; - - return this; - } - - public MaterialBuilder materialType(MaterialType materialType) { - this.materialType = materialType; - - return this; - } - - public Material build() { - return new Material(id, name, inventoryQuantity, isMixType, materialType); - } -} diff --git a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/MaterialTypeBuilder.java b/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/MaterialTypeBuilder.java deleted file mode 100644 index e9acad1..0000000 --- a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/MaterialTypeBuilder.java +++ /dev/null @@ -1,39 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.builders; - -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; - -public class MaterialTypeBuilder { - - private Long id = 0L; - private String name = "Base"; - private String prefix = "BAS"; - private boolean usePercentages = false; - - public MaterialTypeBuilder id(Long id) { - this.id = id; - - return this; - } - - public MaterialTypeBuilder name(String name) { - this.name = name; - - return this; - } - - public MaterialTypeBuilder prefix(String prefix) { - this.prefix = prefix; - - return this; - } - - public MaterialTypeBuilder usePercentages(boolean usePercentages) { - this.usePercentages = usePercentages; - - return this; - } - - public MaterialType build() { - return new MaterialType(id, name, prefix, usePercentages); - } -} diff --git a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/MixTypeBuilder.java b/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/MixTypeBuilder.java deleted file mode 100644 index fccab54..0000000 --- a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/builders/MixTypeBuilder.java +++ /dev/null @@ -1,35 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.builders; - -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixType; -import lombok.NonNull; - -import javax.validation.constraints.NotNull; - -public class MixTypeBuilder { - private Long id = 0L; - private String name = "Lacque Coloré"; - private Material material = new MaterialBuilder().build(); - - public MixTypeBuilder() { - } - - public MixTypeBuilder id(Long val) { - id = val; - return this; - } - - public MixTypeBuilder name(@NonNull @NotNull String val) { - name = val; - return this; - } - - public MixTypeBuilder material(@NonNull @NotNull Material val) { - material = val; - return this; - } - - public MixType build() { - return new MixType(id, name, material); - } -} diff --git a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/AbstractServiceTest.java b/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/AbstractServiceTest.java deleted file mode 100644 index e7063d8..0000000 --- a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/AbstractServiceTest.java +++ /dev/null @@ -1,248 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.services; - -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.NullIdentifierException; -import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel; -import dev.fyloz.trial.colorrecipesexplorer.core.services.IGenericService; -import org.junit.jupiter.api.Test; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.*; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.Mockito.*; - -public abstract class AbstractServiceTest, R extends JpaRepository> { - - private S service; - private R repository; - - public void init(S service, R repository) { - this.service = service; - this.repository = repository; - - E entity = getEntity(); - - when(repository.existsById(anyLong())).thenReturn(false); - when(repository.existsById(entity.getId())).thenReturn(true); - - when(repository.findById(anyLong())).thenReturn(Optional.empty()); - when(repository.findById(entity.getId())).thenReturn(Optional.of(entity)); - - when(repository.save(any())).thenAnswer(i -> i.getArgument(0)); - } - - - - @Test - public void whenExistsById_thenReturnTrue() { - // given - E entity = getEntity(); - - // when - boolean found = service.existsById(entity.getId()); - - // then - assertTrue(found); - } - - @Test - public void whenExistsById_thenReturnFalse() { - // given - E entity = getEntityDifferentId(); - - // when - boolean found = service.existsById(entity.getId()); - - // then - assertFalse(found); - } - - @Test - public void whenGetById_thenReturnEntity() { - // given - E entity = getEntity(); - - // when - E found = service.getById(entity.getId()); - - // then - assertEquals(entity, found); - } - - @Test - public void whenGetById_thenThrowEntityNotFoundException() { - // given - E entity = getEntityDifferentId(); - - // when - EntityNotFoundException thrown = assertThrows(EntityNotFoundException.class, () -> service.getById(entity.getId())); - assertEquals(thrown.getIdentifierType(), ModelException.IdentifierType.ID); - } - - @Test - public void whenGetAll_thenReturnEntityList() { - // given - E entity = getEntity(); - E anotherEntity = getEntityDifferentId(); - List entities = Arrays.asList(entity, anotherEntity); - - when(repository.findAll()).thenReturn(entities); - - // when - List found = service.getAll(); - - // then - assertFalse(found.isEmpty()); - assertTrue(found.containsAll(entities)); - } - - @Test - public void whenGetAll_thenReturnEmptyList() { - // given - when(repository.findAll()).thenReturn(new ArrayList<>()); - - // when - List found = service.getAll(); - - // then - assertTrue(found.isEmpty()); - } - - @Test - public void whenSave_thenReturnEntity() { - // given - E entity = getEntityDifferentId(); - - // when - E found = service.save(entity); - - // then - assertEquals(entity, found); - } - - @Test - public void whenSave_thenThrowEntityAlreadyExistsException() { - // given - E entity = getEntity(); - - // then - EntityAlreadyExistsException thrown = assertThrows(EntityAlreadyExistsException.class, () -> service.save(entity)); - assertEquals(thrown.getIdentifierType(), ModelException.IdentifierType.ID); - } - - @Test - public void whenSaveAll_thenReturnEntityCollection() { - // given - E entity = getEntity(); - E anotherEntity = getEntityDifferentId(); - List entities = Arrays.asList(entity, anotherEntity); - - doAnswer(i -> i.getArgument(0)).when(service).saveAll(any()); - - // when - Collection found = service.saveAll(entities); - - // then - assertFalse(found.isEmpty()); - assertTrue(found.containsAll(entities)); - } - - @Test - public void whenSaveAll_thenReturnEmptyCollection() { - // given - List entities = new ArrayList<>(); - - doAnswer(i -> i.getArgument(0)).when(service).saveAll(any()); - - // when - Collection found = service.saveAll(entities); - - // then - assertTrue(found.isEmpty()); - } - - @Test - public void whenUpdate_thenReturnEntity() { - // given - E entity = getEntity(); - - // when - E found = service.update(entity); - - // then - assertEquals(entity, found); - } - - @Test - public void whenUpdate_thenThrowNullIdentifierException() { - // given - E entity = getEntityNullId(); - - // then - assertThrows(NullIdentifierException.class, () -> service.update(entity)); - } - - @Test - public void whenUpdate_thenThrowEntityNotFoundException() { - // given - E entity = getEntityDifferentId(); - - // when - EntityNotFoundException thrown = assertThrows(EntityNotFoundException.class, () -> service.update(entity)); - - // then - assertEquals(thrown.getIdentifierType(), ModelException.IdentifierType.ID); - } - - @Test - public void whenDelete_thenDaoIsCalled() { - // given - E entity = getEntity(); - - // when - service.delete(entity); - - // then - verify(repository).delete(entity); - } - - @Test - public void whenDeleteById_thenDeleteIsCalled() { - // given - E entity = getEntity(); - - // when - service.deleteById(entity.getId()); - - // then - verify(service).delete(entity); - } - - @Test - public void whenDeleteAll_thenDaoIsCalled() { - // given - E entity = getEntity(); - E anotherEntity = getEntityDifferentId(); - Collection entities = Arrays.asList(entity, anotherEntity); - - // when - service.deleteAll(entities); - - // then - verify(repository).deleteAll(entities); - } - - - - protected abstract E getEntity(); - - protected abstract E getEntityDifferentId(); - - protected abstract E getEntityNullId(); - -} diff --git a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/CompanyServiceTest.java b/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/CompanyServiceTest.java deleted file mode 100644 index 051ee6c..0000000 --- a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/CompanyServiceTest.java +++ /dev/null @@ -1,165 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.services; - -import dev.fyloz.trial.colorrecipesexplorer.builders.CompanyBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityLinkedException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Company; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.CompanyService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; -import dev.fyloz.trial.colorrecipesexplorer.dao.CompanyDao; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; - -@ExtendWith(SpringExtension.class) -@SpringBootTest -public class CompanyServiceTest extends AbstractServiceTest { - - @MockBean - private CompanyDao companyDao; - - @Autowired - @SpyBean - private CompanyService companyService; - - @MockBean - private RecipeService recipeService; - - @BeforeEach - public void setUp() { - companyService.setCompanyDao(companyDao); - companyService.setRecipeService(recipeService); - - super.init(companyService, companyDao); - - Company company = getEntityDifferentName(); - - when(companyDao.existsByName(anyString())).thenReturn(false); - when(companyDao.existsByName(company.getName())).thenReturn(true); - - when(recipeService.existsByCompany(any())).thenReturn(false); - when(recipeService.existsByCompany(company)).thenReturn(true); - } - - - @Test - public void whenExistsByName_thenReturnTrue() { - // given - Company company = getEntityDifferentName(); - - // when - boolean found = companyService.existsByName(company.getName()); - - // then - assertTrue(found); - } - - @Test - public void whenExistsByName_thenReturnFalse() { - // given - Company company = getEntity(); - - // when - boolean found = companyService.existsByName(company.getName()); - - // then - assertFalse(found); - } - - @Test - public void whenIsLinkedToRecipes_thenReturnTrue() { - // given - Company company = getEntityDifferentName(); - - // when - boolean found = companyService.isLinkedToRecipes(company); - - // then - assertTrue(found); - } - - @Test - public void whenIsLinkedToRecipes_thenReturnFalse() { - // given - Company company = getEntity(); - - // when - boolean found = companyService.isLinkedToRecipes(company); - - // then - assertFalse(found); - } - - @Test - @Override - public void whenSave_thenReturnEntity() { - // given - Company company = getEntityDifferentId(); - - // when - Company found = companyService.save(company); - - // then - assertEquals(company, found); - } - - @Test - @Override - public void whenSave_thenThrowEntityAlreadyExistsException() { - // given - Company company = getEntityDifferentName(); - - // when - EntityAlreadyExistsException thrown = assertThrows(EntityAlreadyExistsException.class, () -> companyService.save(company)); - - // then - assertEquals(thrown.getIdentifierType(), ModelException.IdentifierType.NAME); - - super.whenSave_thenThrowEntityAlreadyExistsException(); - } - - @Test - public void whenDelete_thenThrowEntityLinkedException() { - // given - Company company = getEntityDifferentName(); - - // then - assertThrows(EntityLinkedException.class, () -> companyService.delete(company)); - } - - @Override - protected Company getEntity() { - return new CompanyBuilder().build(); - } - - @Override - protected Company getEntityDifferentId() { - return new CompanyBuilder() - .id(1L) - .build(); - } - - @Override - protected Company getEntityNullId() { - return new CompanyBuilder() - .id(null) - .build(); - } - - private Company getEntityDifferentName() { - return new CompanyBuilder() - .name("Design") - .build(); - } -} diff --git a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/MaterialServiceTest.java b/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/MaterialServiceTest.java deleted file mode 100644 index 19f8324..0000000 --- a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/MaterialServiceTest.java +++ /dev/null @@ -1,296 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.services; - -import dev.fyloz.trial.colorrecipesexplorer.builders.MaterialBuilder; -import dev.fyloz.trial.colorrecipesexplorer.builders.MaterialTypeBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import dev.fyloz.trial.colorrecipesexplorer.core.services.files.SimdutService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MixQuantityService; -import dev.fyloz.trial.colorrecipesexplorer.dao.MaterialDao; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; - -@ExtendWith(SpringExtension.class) -@SpringBootTest -public class MaterialServiceTest extends AbstractServiceTest { - - @MockBean - private MaterialDao materialDao; - - @Autowired - @SpyBean - private MaterialService materialService; - - @MockBean - private MixQuantityService mixQuantityService; - - @MockBean - private SimdutService simdutService; - - @BeforeEach - void setUp() { - materialService.setMaterialDao(materialDao); - materialService.setMixQuantityService(mixQuantityService); - materialService.setSimdutService(simdutService); - - super.init(materialService, materialDao); - - Material material = getEntityDifferentName(); - MaterialType materialType = getMaterialType(); - - when(materialDao.existsByName(anyString())).thenReturn(false); - when(materialDao.existsByName(material.getName())).thenReturn(true); - - when(materialDao.findByName(anyString())).thenReturn(Optional.empty()); - when(materialDao.findByName(material.getName())).thenReturn(Optional.of(material)); - - when(materialDao.existsByMaterialType(any())).thenReturn(false); - when(materialDao.existsByMaterialType(materialType)).thenReturn(true); - - when(mixQuantityService.existsByMaterial(any())).thenReturn(false); - when(mixQuantityService.existsByMaterial(material)).thenReturn(true); - } - - - @Test - public void whenExistsByName_thenReturnTrue() { - // given - Material material = getEntityDifferentName(); - - // when - boolean found = materialService.existsByName(material.getName()); - - // then - assertTrue(found); - } - - @Test - public void whenExistsByName_thenReturnFalse() { - // given - Material material = getEntity(); - - // when - boolean found = materialService.existsByName(material.getName()); - - // then - assertFalse(found); - } - - @Test - public void whenExistsByMaterialType_thenReturnTrue() { - // given - MaterialType materialType = getMaterialType(); - - // when - boolean found = materialService.existsByMaterialType(materialType); - - // then - assertTrue(found); - } - - @Test - public void whenExistsByMaterialType_thenReturnFalse() { - // given - MaterialType materialType = new MaterialTypeBuilder().name("Teinture").build(); - - // when - boolean found = materialService.existsByMaterialType(materialType); - - // then - assertFalse(found); - } - - @Test - public void whenIsLinkedToMixes_thenReturnTrue() { - // given - Material material = getEntityDifferentName(); - - // when - boolean found = materialService.isLinkedToMixes(material); - - // then - assertTrue(found); - } - - @Test - public void whenIsLinkedToMixes_thenReturnFalse() { - // given - Material material = getEntity(); - - // when - boolean found = materialService.isLinkedToMixes(material); - - // then - assertFalse(found); - } - - @Test - public void whenGetAllNotMixType_thenReturnMaterialList() { - // given - Material material = getEntity(); - Material anotherMaterial = getEntityMixType(); - List materials = Arrays.asList(material, anotherMaterial); - - doReturn(materials).when(materialService).getAll(); - - // when - List found = materialService.getAllNotMixType(); - - // then - assertFalse(found.isEmpty()); - assertTrue(found.contains(material)); - assertFalse(found.contains(anotherMaterial)); - } - - @Test - public void whenGetByName_thenReturnMaterial() { - // given - Material material = getEntityDifferentName(); - - // when - Material found = materialService.getByName(material.getName()); - - // then - assertEquals(material, found); - } - - @Test - public void whenGetByName_thenThrowEntityNotFoundExceptionName() { - // given - Material material = getEntity(); - - // then - EntityNotFoundException thrown = assertThrows(EntityNotFoundException.class, () -> materialService.getByName(material.getName())); - assertEquals(thrown.getIdentifierType(), ModelException.IdentifierType.NAME); - } - - @Override - @Test - public void whenSave_thenReturnEntity() { - // given - Material material = getEntityDifferentId(); - MockMultipartFile simdut = new MockMultipartFile("simdut", "simdut.pdf", MediaType.APPLICATION_PDF_VALUE, "pdf content".getBytes()); - - // when - Material found = materialService.save(material, simdut); - - //then - verify(simdutService).write(material, simdut); - assertEquals(material, found); - } - - @Test - public void whenUpdate_thenReturnMaterial() { - // given - Material material = getEntityDifferentName(); - - // when - Material found = materialService.update(material); - - // then - assertEquals(material, found); - } - - @Test - public void whenUpdate_thenThrowEntityAlreadyExistsExceptionName() { - // given - Material material = getEntityDifferentName(); - Material anotherMaterial = getEntityDifferentNameAndId(); - - when(materialDao.findByName(anotherMaterial.getName())).thenReturn(Optional.of(anotherMaterial)); - - // then - EntityAlreadyExistsException thrown = assertThrows(EntityAlreadyExistsException.class, () -> materialService.update(material)); - assertEquals(thrown.getIdentifierType(), ModelException.IdentifierType.NAME); - } - - @Test - public void whenUpdate_thenSimdutServiceIsCalled() { - // given - Material material = getEntityDifferentName(); - MockMultipartFile simdut = new MockMultipartFile("simdut", "simdut.pdf", MediaType.APPLICATION_PDF_VALUE, "pdf content".getBytes()); - - // when - Material found = materialService.update(material, simdut); - - // then - assertEquals(material, found); - verify(simdutService).update(simdut, found); - } - - @Test - public void whenDelete_thenSimdutServiceIsCalled() { - // given - Material material = getEntityDifferentName(); - - // when - materialService.delete(material); - - // then - verify(simdutService).delete(material); - } - - - @Override - protected Material getEntity() { - return new MaterialBuilder().build(); - } - - @Override - protected Material getEntityDifferentId() { - return new MaterialBuilder() - .id(1L) - .build(); - } - - @Override - protected Material getEntityNullId() { - return new MaterialBuilder() - .id(null) - .build(); - } - - private Material getEntityDifferentName() { - return new MaterialBuilder() - .name("Dirt") - .build(); - } - - private Material getEntityDifferentNameAndId() { - return new MaterialBuilder() - .id(1L) - .name("Dirt") - .build(); - } - - private Material getEntityMixType() { - return new MaterialBuilder() - .mixType(true) - .build(); - } - - private MaterialType getMaterialType() { - return new MaterialTypeBuilder().build(); - } -} diff --git a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/MaterialTypeServiceTest.java b/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/MaterialTypeServiceTest.java deleted file mode 100644 index 6551a2c..0000000 --- a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/MaterialTypeServiceTest.java +++ /dev/null @@ -1,355 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.services; - -import dev.fyloz.trial.colorrecipesexplorer.builders.MaterialTypeBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.CannotDeleteDefaultMaterialTypeException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.CannotEditDefaultMaterialTypeException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityAlreadyExistsException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; -import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MaterialTypeEditorDto; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService; -import dev.fyloz.trial.colorrecipesexplorer.dao.MaterialTypeDao; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mockito; -import org.mockito.Spy; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -@ExtendWith(SpringExtension.class) -@SpringBootTest -public class MaterialTypeServiceTest extends AbstractServiceTest { - - @MockBean - private MaterialTypeDao materialTypeDao; - - @Autowired - @SpyBean - private MaterialTypeService materialTypeService; - - @MockBean - private MaterialService materialService; - - @Spy - private List defaultMaterialTypes = new LinkedList<>(); - - @BeforeEach - void setUp() { - materialTypeService.setMaterialTypeDao(materialTypeDao); - materialTypeService.setMaterialService(materialService); - materialTypeService.setDefaultMaterialTypes(defaultMaterialTypes); - - super.init(materialTypeService, materialTypeDao); - - MaterialType materialType = getEntity(); - MaterialType nameMaterialType = getEntityDifferentName(); - MaterialType prefixMaterialType = getEntityDifferentPrefix(); - - doReturn(false).when(defaultMaterialTypes).contains(Mockito.any()); - doReturn(true).when(defaultMaterialTypes).contains(materialType); - - when(materialTypeDao.existsByName(anyString())).thenReturn(false); - when(materialTypeDao.existsByName(nameMaterialType.getName())).thenReturn(true); - - when(materialTypeDao.existsByPrefix(anyString())).thenReturn(false); - when(materialTypeDao.existsByPrefix(prefixMaterialType.getPrefix())).thenReturn(true); - - when(materialService.existsByMaterialType(any())).thenReturn(false); - when(materialService.existsByMaterialType(materialType)).thenReturn(true); - - when(materialTypeDao.findByName(anyString())).thenReturn(Optional.empty()); - when(materialTypeDao.findByName(nameMaterialType.getName())).thenReturn(Optional.of(nameMaterialType)); - } - - - @Test - public void whenAddDefault_thenListIsCalled() { - // given - MaterialType materialType = getEntity(); - - // when - materialTypeService.addDefault(materialType); - - // then - verify(defaultMaterialTypes).add(materialType); - } - - @Test - public void whenIsDefault_thenReturnTrue() { - // given - MaterialType materialType = getEntity(); - - // when - boolean found = materialTypeService.isDefault(materialType); - - // then - assertTrue(found); - } - - @Test - public void whenIsDefault_thenReturnFalse() { - // given - MaterialType materialType = getEntityDifferentName(); - - // when - boolean found = materialTypeService.isDefault(materialType); - - // then - assertFalse(found); - } - - @Test - public void whenExistsByName_thenReturnTrue() { - // given - MaterialType materialType = getEntityDifferentName(); - - // when - boolean found = materialTypeService.existsByName(materialType.getName()); - - // then - assertTrue(found); - } - - @Test - public void whenExistsByName_thenReturnFalse() { - // given - MaterialType materialType = getEntity(); - - // when - boolean found = materialTypeService.existsByName(materialType.getName()); - - // then - assertFalse(found); - } - - @Test - public void whenExistsByPrefix_thenReturnTrue() { - // given - MaterialType materialType = getEntityDifferentPrefix(); - - // when - boolean found = materialTypeService.existsByPrefix(materialType.getPrefix()); - - // then - assertTrue(found); - } - - @Test - public void whenExistsByPrefix_thenReturnFalse() { - // given - MaterialType materialType = getEntity(); - - // when - boolean found = materialTypeService.existsByPrefix(materialType.getPrefix()); - - // then - assertFalse(found); - } - - @Test - public void whenIsLinkedToMaterials_thenReturnTrue() { - // given - MaterialType materialType = getEntity(); - - // when - boolean found = materialTypeService.isLinkedToMaterials(materialType); - - // then - assertTrue(found); - } - - @Test - public void whenIsLinkedToMaterials_thenReturnFalse() { - // given - MaterialType materialType = getEntityDifferentName(); - - // when - boolean found = materialTypeService.isLinkedToMaterials(materialType); - - // then - assertFalse(found); - } - - @Test - public void whenGetAllNotDefault_thenReturnMaterialTypeList() { - // given - MaterialType defaultMaterialType = getEntity(); - MaterialType materialType = getEntityDifferentName(); - List materialTypes = Arrays.asList(defaultMaterialType, materialType); - - doReturn(materialTypes).when(materialTypeService).getAll(); - - // when - List found = materialTypeService.getAllNotDefault(); - - // then - assertFalse(found.isEmpty()); - assertTrue(found.contains(materialType)); - assertFalse(found.contains(defaultMaterialType)); - } - - @Test - public void whenGetByName_thenReturnTrue() { - // given - MaterialType materialType = getEntityDifferentName(); - - // when - MaterialType found = materialTypeService.getByName(materialType.getName()); - - // then - assertEquals(materialType, found); - } - - @Test - public void whenGetByName_thenThrowEntityNotFoundExceptionName() { - // given - MaterialType materialType = getEntity(); - - // then - EntityNotFoundException thrown = assertThrows(EntityNotFoundException.class, () -> materialTypeService.getByName(materialType.getName())); - assertEquals(thrown.getIdentifierType(), ModelException.IdentifierType.NAME); - } - - @Test - public void whenUpdate_thenReturnMaterialType() { - // given - MaterialType materialType = getEntityDifferentName(); - MaterialTypeEditorDto dto = new MaterialTypeEditorDto(materialType); - - doReturn(false).when(materialTypeService).isDefault(materialType); - - // when - MaterialType found = materialTypeService.update(dto); - - // then - assertEquals(materialType, found); - } - - @Test - public void whenUpdate_thenThrowCannotEditDefaultMaterialTypeException() { - // given - MaterialType materialType = getEntity(); - - // then - assertThrows(CannotEditDefaultMaterialTypeException.class, () -> materialTypeService.update(new MaterialTypeEditorDto(materialType))); - } - - @Test - public void whenUpdate_thenThrowEntityNotFoundExceptionOldName() { - // given - MaterialType materialType = getEntityDifferentPrefix(); - - // then - EntityNotFoundException thrown = assertThrows(EntityNotFoundException.class, () -> materialTypeService.update(new MaterialTypeEditorDto(materialType))); - assertEquals(thrown.getIdentifierType(), ModelException.IdentifierType.NAME); - } - - @Test - public void whenUpdate_thenThrowEntityAlreadyExistsExceptionName() { - // given - MaterialType materialType = getEntityDifferentName(); - MaterialTypeEditorDto dto = new MaterialTypeEditorDto(materialType); - dto.setOldName("Base"); - - doReturn(false).when(materialTypeService).isDefault(dto.getOldMaterialType()); - doReturn(true).when(materialTypeService).existsByName(dto.getOldName()); - - // then - EntityAlreadyExistsException thrown = assertThrows(EntityAlreadyExistsException.class, () -> materialTypeService.update(dto)); - assertEquals(thrown.getIdentifierType(), ModelException.IdentifierType.NAME); - } - - @Test - public void whenUpdate_thenThrowEntityAlreadyExistsExceptionPrefix() { - // given - MaterialType materialType = getEntityDifferentPrefix(); - MaterialTypeEditorDto dto = new MaterialTypeEditorDto(materialType); - dto.setOldPrefix("BAS"); - dto.setName("Catalyseur"); - dto.setOldName("Catalyseur"); - - // then - EntityAlreadyExistsException thrown = assertThrows(EntityAlreadyExistsException.class, () -> materialTypeService.update(dto)); - assertEquals(thrown.getIdentifierType(), ModelException.IdentifierType.OTHER); - assertEquals(thrown.getIdentifierName(), MaterialType.IDENTIFIER_PREFIX_NAME); - } - - @Override - public void whenDelete_thenDaoIsCalled() { - // given - MaterialType materialType = getEntityDifferentName(); - - // when - materialTypeService.delete(materialType); - - // then - verify(materialTypeDao).delete(materialType); - } - - @Test - public void whenDelete_thenThrowCannotDeleteDefaultMaterialTypeException() { - // given - MaterialType materialType = getEntity(); - - // then - assertThrows(CannotDeleteDefaultMaterialTypeException.class, () -> materialTypeService.delete(materialType)); - } - - @Override - public void whenDeleteById_thenDeleteIsCalled() { - // given - MaterialType materialType = getEntityDifferentId(); - - // when - materialTypeService.deleteById(materialType.getId()); - - // then - verify(materialTypeService).delete(materialType); - } - - @Override - protected MaterialType getEntity() { - return new MaterialTypeBuilder().build(); - } - - @Override - protected MaterialType getEntityDifferentId() { - return new MaterialTypeBuilder() - .id(1L) - .build(); - } - - @Override - protected MaterialType getEntityNullId() { - return new MaterialTypeBuilder() - .id(null) - .build(); - } - - private MaterialType getEntityDifferentName() { - return new MaterialTypeBuilder() - .name("Catalyseur") - .build(); - } - - private MaterialType getEntityDifferentPrefix() { - return new MaterialTypeBuilder() - .prefix("CAT") - .build(); - } -} diff --git a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/MixTypeServiceTest.java b/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/MixTypeServiceTest.java deleted file mode 100644 index 0cd3b45..0000000 --- a/src/tests/java/dev/fyloz/trial/colorrecipesexplorer/services/MixTypeServiceTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package dev.fyloz.trial.colorrecipesexplorer.services; - -import dev.fyloz.trial.colorrecipesexplorer.builders.MixTypeBuilder; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixType; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MixTypeService; -import dev.fyloz.trial.colorrecipesexplorer.dao.MixTypeDao; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; - -public class MixTypeServiceTest extends AbstractServiceTest { - - @MockBean - private MixTypeDao mixTypeDao; - - @Autowired - @SpyBean - private MixTypeService mixTypeService; - - @MockBean - private MaterialService materialService; - - @BeforeEach - void setUp() { - mixTypeService.setMixTypeDao(mixTypeDao); - mixTypeService.setMaterialService(materialService); - - super.init(mixTypeService, mixTypeDao); - - - } - - - @Test - public void whenExistsByName_thenReturnTrue() { - // given - - // when - - // then - - } - - - @Override - protected MixType getEntity() { - return new MixTypeBuilder().build(); - } - - @Override - protected MixType getEntityDifferentId() { - return new MixTypeBuilder() - .id(1L) - .build(); - } - - @Override - protected MixType getEntityNullId() { - return new MixTypeBuilder() - .id(null) - .build(); - } -}