diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/ColorRecipesExplorerApplication.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/ColorRecipesExplorerApplication.kt index 13cef5b..409d4ca 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/ColorRecipesExplorerApplication.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/ColorRecipesExplorerApplication.kt @@ -5,8 +5,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration import org.springframework.boot.builder.SpringApplicationBuilder import org.springframework.context.ConfigurableApplicationContext +import org.springframework.scheduling.annotation.EnableScheduling @SpringBootApplication(exclude = [LiquibaseAutoConfiguration::class]) +@EnableScheduling class ColorRecipesExplorerApplication var emergencyMode = false diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/ConfigurationsInitializer.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/ConfigurationsInitializer.kt index b1574ed..0a08037 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/ConfigurationsInitializer.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/ConfigurationsInitializer.kt @@ -3,7 +3,7 @@ package dev.fyloz.colorrecipesexplorer.config import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties import dev.fyloz.colorrecipesexplorer.model.ConfigurationType import dev.fyloz.colorrecipesexplorer.model.configuration -import dev.fyloz.colorrecipesexplorer.service.files.create +import dev.fyloz.colorrecipesexplorer.service.create import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import java.io.File diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt index 9cb732c..5284285 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt @@ -87,6 +87,7 @@ enum class ConfigurationType( DATABASE_SUPPORTED_VERSION("database.version.supported", computed = true), TOUCH_UP_KIT_CACHE_PDF("touchupkit.pdf.cache"), + TOUCH_UP_KIT_EXPIRATION("touchupkit.expiration"), EMERGENCY_MODE_ENABLED("env.emergency", computed = true, public = true), VERSION("env.version", computed = true), diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/touchupkit/TouchUpKit.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/touchupkit/TouchUpKit.kt index e6a01ed..1a90530 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/touchupkit/TouchUpKit.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/touchupkit/TouchUpKit.kt @@ -31,6 +31,9 @@ data class TouchUpKit( @Column(name = "shipping_date") val shippingDate: LocalDate, + @Column(name = "completion_date") + val completionDate: LocalDate?, + @Column(name = "finish") private val finishConcatenated: String, @@ -46,6 +49,9 @@ data class TouchUpKit( val material get() = materialConcatenated.split(TOUCH_UP_KIT_DELIMITER) + + val completed + get() = completionDate != null } @Entity @@ -59,7 +65,9 @@ data class TouchUpKitProduct( val description: String?, - val quantity: Float + val quantity: Float, + + val ready: Boolean ) : Model data class TouchUpKitSaveDto( @@ -106,6 +114,8 @@ data class TouchUpKitUpdateDto( val shippingDate: LocalDate?, + val completionDate: LocalDate?, + @field:NotEmpty val finish: List?, @@ -123,6 +133,9 @@ data class TouchUpKitOutputDto( val company: String, val quantity: Int, val shippingDate: LocalDate, + val completed: Boolean, + val completionDate: LocalDate?, + val expired: Boolean, val finish: List, val material: List, val content: Set, @@ -132,7 +145,8 @@ data class TouchUpKitOutputDto( data class TouchUpKitProductDto( val name: String, val description: String?, - val quantity: Float + val quantity: Float, + val ready: Boolean ) // ==== DSL ==== @@ -143,6 +157,7 @@ fun touchUpKit( company: String = "company", quantity: Int = 1, shippingDate: LocalDate = LocalDate.now(), + completionDate: LocalDate? = null, finish: List, material: List, content: Set, @@ -154,6 +169,7 @@ fun touchUpKit( company, quantity, shippingDate, + completionDate, finish.reduce { acc, f -> "$acc$TOUCH_UP_KIT_DELIMITER$f" }, material.reduce { acc, f -> "$acc$TOUCH_UP_KIT_DELIMITER$f" }, content @@ -178,15 +194,30 @@ fun touchUpKitProduct( name: String = "product", description: String? = "description", quantity: Float = 1f, + ready: Boolean = false, op: TouchUpKitProduct.() -> Unit = {} -) = TouchUpKitProduct(id, name, description, quantity) +) = TouchUpKitProduct(id, name, description, quantity, ready) .apply(op) +fun touchUpKitUpdateDto( + id: Long = 0L, + project: String? = null, + buggy: String? = null, + company: String? = null, + quantity: Int? = null, + shippingDate: LocalDate? = null, + completionDate: LocalDate? = null, + finish: List? = null, + material: List? = null, + content: Set? = null +) = TouchUpKitUpdateDto(id, project, buggy, company, quantity, shippingDate, completionDate, finish, material, content) + fun touchUpKitProduct(touchUpKitProductDto: TouchUpKitProductDto) = touchUpKitProduct( name = touchUpKitProductDto.name, description = touchUpKitProductDto.description, - quantity = touchUpKitProductDto.quantity + quantity = touchUpKitProductDto.quantity, + ready = touchUpKitProductDto.ready ) // ==== Exceptions ==== diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/FileController.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/FileController.kt index e91186c..ded4d51 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/FileController.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/FileController.kt @@ -2,7 +2,7 @@ package dev.fyloz.colorrecipesexplorer.rest import dev.fyloz.colorrecipesexplorer.model.ConfigurationType import dev.fyloz.colorrecipesexplorer.service.ConfigurationService -import dev.fyloz.colorrecipesexplorer.service.files.FileService +import dev.fyloz.colorrecipesexplorer.service.FileService import org.springframework.core.io.ByteArrayResource import org.springframework.http.MediaType import org.springframework.http.ResponseEntity diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/TouchUpKitController.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/TouchUpKitController.kt index 8e27621..e9cbe47 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/TouchUpKitController.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/TouchUpKitController.kt @@ -3,7 +3,7 @@ package dev.fyloz.colorrecipesexplorer.rest import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitOutputDto import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitSaveDto import dev.fyloz.colorrecipesexplorer.model.touchupkit.TouchUpKitUpdateDto -import dev.fyloz.colorrecipesexplorer.service.touchupkit.TouchUpKitService +import dev.fyloz.colorrecipesexplorer.service.TouchUpKitService import org.springframework.context.annotation.Profile import org.springframework.core.io.ByteArrayResource import org.springframework.http.MediaType @@ -40,17 +40,21 @@ class TouchUpKitController( @PutMapping @PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')") - fun update(@Valid @RequestBody touchUpKit: TouchUpKitUpdateDto) = - noContent { - touchUpKitService.update(touchUpKit) - } + fun update(@Valid @RequestBody touchUpKit: TouchUpKitUpdateDto) = noContent { + touchUpKitService.update(touchUpKit) + } + + @PutMapping("{id}/complete") + @PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')") + fun complete(@PathVariable id: Long) = noContent { + touchUpKitService.complete(id) + } @DeleteMapping("{id}") @PreAuthorize("hasAuthority('EDIT_TOUCH_UP_KITS')") - fun deleteById(@PathVariable id: Long) = - noContent { - touchUpKitService.deleteById(id) - } + fun deleteById(@PathVariable id: Long) = noContent { + touchUpKitService.deleteById(id) + } @GetMapping("pdf") fun getJobPdf(@RequestParam project: String): ResponseEntity { diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/ConfigurationService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/ConfigurationService.kt index d18384d..0dd69e0 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/ConfigurationService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/ConfigurationService.kt @@ -7,12 +7,11 @@ import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties import dev.fyloz.colorrecipesexplorer.emergencyMode import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.repository.ConfigurationRepository -import dev.fyloz.colorrecipesexplorer.service.files.FileService import org.springframework.boot.info.BuildProperties import org.springframework.context.annotation.Lazy import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service -import java.io.File +import java.time.Period import javax.annotation.PostConstruct interface ConfigurationService { @@ -132,6 +131,7 @@ class ConfigurationServiceImpl( ConfigurationType.DATABASE_USER -> databaseProperties.username ConfigurationType.DATABASE_PASSWORD -> databaseProperties.password ConfigurationType.TOUCH_UP_KIT_CACHE_PDF -> "true" + ConfigurationType.TOUCH_UP_KIT_EXPIRATION -> Period.ofMonths(1).toString() else -> "" } diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/FileService.kt similarity index 99% rename from src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileService.kt rename to src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/FileService.kt index 5383fbb..69cd4aa 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/FileService.kt @@ -1,4 +1,4 @@ -package dev.fyloz.colorrecipesexplorer.service.files +package dev.fyloz.colorrecipesexplorer.service import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties import dev.fyloz.colorrecipesexplorer.exception.RestException diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialService.kt index ce58533..6d6aad4 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialService.kt @@ -3,7 +3,6 @@ package dev.fyloz.colorrecipesexplorer.service import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.repository.MaterialRepository import dev.fyloz.colorrecipesexplorer.rest.FILE_CONTROLLER_PATH -import dev.fyloz.colorrecipesexplorer.service.files.FileService import io.jsonwebtoken.lang.Assert import org.springframework.context.annotation.Lazy import org.springframework.context.annotation.Profile diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeService.kt index ee26293..e34b48d 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeService.kt @@ -4,7 +4,6 @@ import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.model.account.Group import dev.fyloz.colorrecipesexplorer.model.validation.or import dev.fyloz.colorrecipesexplorer.repository.RecipeRepository -import dev.fyloz.colorrecipesexplorer.service.files.FileService import dev.fyloz.colorrecipesexplorer.utils.setAll import org.springframework.context.annotation.Lazy import org.springframework.context.annotation.Profile diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/touchupkit/TouchUpKitService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/TouchUpKitService.kt similarity index 87% rename from src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/touchupkit/TouchUpKitService.kt rename to src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/TouchUpKitService.kt index e847ec2..59bc4b8 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/touchupkit/TouchUpKitService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/TouchUpKitService.kt @@ -1,18 +1,16 @@ -package dev.fyloz.colorrecipesexplorer.service.touchupkit +package dev.fyloz.colorrecipesexplorer.service import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties import dev.fyloz.colorrecipesexplorer.model.ConfigurationType import dev.fyloz.colorrecipesexplorer.model.touchupkit.* import dev.fyloz.colorrecipesexplorer.repository.TouchUpKitRepository import dev.fyloz.colorrecipesexplorer.rest.TOUCH_UP_KIT_CONTROLLER_PATH -import dev.fyloz.colorrecipesexplorer.service.AbstractExternalModelService -import dev.fyloz.colorrecipesexplorer.service.ConfigurationService -import dev.fyloz.colorrecipesexplorer.service.ExternalModelService -import dev.fyloz.colorrecipesexplorer.service.files.FileService import dev.fyloz.colorrecipesexplorer.utils.* import org.springframework.context.annotation.Profile import org.springframework.core.io.ByteArrayResource import org.springframework.stereotype.Service +import java.time.LocalDate +import java.time.Period private const val TOUCH_UP_KIT_FILES_PATH = "pdf/touchupkits" @@ -21,6 +19,10 @@ const val TOUCH_UP_TEXT_EN = "TOUCH UP KIT" interface TouchUpKitService : ExternalModelService { + fun isExpired(touchUpKit: TouchUpKit): Boolean + + fun complete(id: Long) + /** Generates and returns a [PdfDocument] for the given [job]. */ fun generateJobPdf(job: String): PdfDocument @@ -55,6 +57,9 @@ class TouchUpKitServiceImpl( this.company, this.quantity, this.shippingDate, + this.completionDate != null, + this.completionDate, + isExpired(this), this.finish, this.material, this.content, @@ -79,6 +84,15 @@ class TouchUpKitServiceImpl( }) } + override fun isExpired(touchUpKit: TouchUpKit) = + with(Period.parse(configService.get(ConfigurationType.TOUCH_UP_KIT_EXPIRATION).content)) { + touchUpKit.completed && touchUpKit.completionDate!!.plus(this) < LocalDate.now() + } + + override fun complete(id: Long) { + update(touchUpKitUpdateDto(id = id, completionDate = LocalDate.now())) + } + override fun generateJobPdf(job: String) = pdf { container { centeredVertically = true diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/jobs/TouchUpKitRemover.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/jobs/TouchUpKitRemover.kt new file mode 100644 index 0000000..7fd45ab --- /dev/null +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/jobs/TouchUpKitRemover.kt @@ -0,0 +1,25 @@ +package dev.fyloz.colorrecipesexplorer.service.jobs + +import dev.fyloz.colorrecipesexplorer.service.TouchUpKitService +import org.slf4j.Logger +import org.springframework.scheduling.annotation.Scheduled +import org.springframework.stereotype.Component + +@Component +class TouchUpKitRemover( + private val touchUpKitService: TouchUpKitService, + private val logger: Logger +) { + @Scheduled(cron = "0 0 0 * * *") + fun execute() { + removeExpiredKits() + } + + private fun removeExpiredKits() { + logger.info("Removing expired touch up kits...") + with(touchUpKitService.getAll().filter(touchUpKitService::isExpired)) { + this.forEach(touchUpKitService::delete) + logger.info("Removed ${this.size} expired touch up kits") + } + } +} diff --git a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialServiceTest.kt b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialServiceTest.kt index dd42bf2..0962323 100644 --- a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialServiceTest.kt @@ -4,7 +4,7 @@ import com.nhaarman.mockitokotlin2.* import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.repository.MaterialRepository -import dev.fyloz.colorrecipesexplorer.service.files.FileService +import dev.fyloz.colorrecipesexplorer.service.FileService import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance diff --git a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeServiceTest.kt b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeServiceTest.kt index 8d4e612..9078af9 100644 --- a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeServiceTest.kt @@ -5,7 +5,7 @@ import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException import dev.fyloz.colorrecipesexplorer.model.* import dev.fyloz.colorrecipesexplorer.model.account.group import dev.fyloz.colorrecipesexplorer.repository.RecipeRepository -import dev.fyloz.colorrecipesexplorer.service.files.FileService +import dev.fyloz.colorrecipesexplorer.service.FileService import io.mockk.* import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileServiceTest.kt b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileServiceTest.kt index 6e8b7ac..c414c9a 100644 --- a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileServiceTest.kt @@ -1,4 +1,4 @@ -package dev.fyloz.colorrecipesexplorer.service.files +package dev.fyloz.colorrecipesexplorer.service import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties import io.mockk.* diff --git a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/TouchUpKitServiceTest.kt b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/TouchUpKitServiceTest.kt index cdbebf7..c81244a 100644 --- a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/TouchUpKitServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/TouchUpKitServiceTest.kt @@ -1,13 +1,10 @@ -package dev.fyloz.colorrecipesexplorer.service.files +package dev.fyloz.colorrecipesexplorer.service import dev.fyloz.colorrecipesexplorer.config.properties.CreProperties import dev.fyloz.colorrecipesexplorer.model.ConfigurationType import dev.fyloz.colorrecipesexplorer.model.configuration import dev.fyloz.colorrecipesexplorer.repository.TouchUpKitRepository -import dev.fyloz.colorrecipesexplorer.service.ConfigurationService -import dev.fyloz.colorrecipesexplorer.service.touchupkit.TOUCH_UP_TEXT_EN -import dev.fyloz.colorrecipesexplorer.service.touchupkit.TOUCH_UP_TEXT_FR -import dev.fyloz.colorrecipesexplorer.service.touchupkit.TouchUpKitServiceImpl +import dev.fyloz.colorrecipesexplorer.service.* import dev.fyloz.colorrecipesexplorer.utils.PdfDocument import dev.fyloz.colorrecipesexplorer.utils.toByteArrayResource import io.mockk.*