add service layer with ProductService, add deleted_at and unique index to product table

This commit is contained in:
Denis Savosin
2024-09-30 12:40:47 +07:00
parent 2b07944b0e
commit f12839a15f
8 changed files with 82 additions and 6 deletions

View File

@@ -0,0 +1,3 @@
package com.example.demo.exceptions
class UnprocessableException(override val message: String): RuntimeException(message)

View File

@@ -27,6 +27,11 @@ data class Product(
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "updated_at")
val updatedAt: OffsetDateTime?,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "deleted_at")
val deletedAt: OffsetDateTime?,
) {
fun getPriceDouble(): Double = (price.toDouble() / 100).roundTo(2)
fun isDeleted(): Boolean = deletedAt != null
}

View File

@@ -1,13 +1,17 @@
package com.example.demo.provider
import com.example.demo.models.Product
import org.springframework.data.jpa.repository.Query
import org.springframework.data.jdbc.repository.query.Query
import org.springframework.data.repository.CrudRepository
import org.springframework.data.repository.query.Param
import org.springframework.stereotype.Repository
import java.time.OffsetDateTime
import java.util.*
@Repository
interface ProductRepository: CrudRepository<Product, Long> {
@Query(value = "SELECT * FROM Product WHERE guid = :guid")
fun findByGuid(guid: UUID): Product?
@Query(value = "UPDATE Product SET deleted_at = :deletedAt WHERE guid = :guid RETURNING *")
fun softDelete(@Param("guid") guid: UUID, @Param("deletedAt") deletedAt: OffsetDateTime): Product?
}

View File

@@ -0,0 +1,17 @@
package com.example.demo.services
import com.example.demo.exceptions.NotFoundException
import com.example.demo.exceptions.UnprocessableException
import com.example.demo.models.Product
import org.springframework.stereotype.Service
import java.util.*
@Service
interface ProductService {
fun findByGuid(guid: UUID): Product?
fun create(name: String, price: Long, description: String?): Product
@Throws(NotFoundException::class, UnprocessableException::class)
fun delete(guid: UUID): Product?
}

View File

@@ -0,0 +1,48 @@
package com.example.demo.services
import com.example.demo.exceptions.NotFoundException
import com.example.demo.exceptions.UnprocessableException
import com.example.demo.models.Product
import com.example.demo.provider.ProductRepository
import java.time.OffsetDateTime
import java.util.*
class ProductServiceImpl(private val productRepository: ProductRepository): ProductService {
override fun findByGuid(guid: UUID): Product? = productRepository.findByGuid(guid)
override fun create(name: String, price: Long, description: String?): Product {
val product = Product(
id = null,
guid = UUID.randomUUID(),
name = name,
description = description,
price = price,
createdAt = OffsetDateTime.now(),
updatedAt = null,
deletedAt = null,
)
return productRepository.save(product)
}
override fun delete(guid: UUID): Product? {
val product = findByGuid(guid) ?: throw NotFoundException()
if (product.isDeleted()) {
throw UnprocessableException("product already deleted")
}
val deletedProduct = product.copy(
id = product.id!!,
guid = product.guid,
name = product.name,
description = product.description,
price = product.price,
createdAt = product.createdAt,
updatedAt = product.updatedAt,
deletedAt = OffsetDateTime.now(),
)
return productRepository.save(deletedProduct)
}
}