| @@ -0,0 +1,20 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.entity.BaseEntity | |||||
| import jakarta.persistence.* | |||||
| import jakarta.validation.constraints.NotNull | |||||
| @Entity | |||||
| @Table(name = "qc_item") | |||||
| open class QcItem : BaseEntity<Long>() { | |||||
| @NotNull | |||||
| @Column(name = "code") | |||||
| open var code: String? = null | |||||
| @NotNull | |||||
| @Column(name = "name") | |||||
| open var name: String? = null | |||||
| @Column(name = "description") | |||||
| open var description: String? = null | |||||
| } | |||||
| @@ -0,0 +1,11 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.support.AbstractRepository | |||||
| import org.springframework.stereotype.Repository | |||||
| @Repository | |||||
| interface QcItemRepository : AbstractRepository<QcItem, Long> { | |||||
| fun findAllByDeletedIsFalse(): List<QcItem> | |||||
| fun findByCodeAndDeletedIsFalse(code: String): QcItem? | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| package com.ffii.fpsms.modules.master.service | |||||
| import com.ffii.fpsms.modules.master.entity.QcItem | |||||
| import com.ffii.fpsms.modules.master.entity.QcItemRepository | |||||
| import org.springframework.stereotype.Service | |||||
| @Service | |||||
| open class QcItemService( | |||||
| private val qcItemRepository: QcItemRepository | |||||
| ) { | |||||
| open fun allQcItems(): List<QcItem> { | |||||
| return qcItemRepository.findAllByDeletedIsFalse() | |||||
| } | |||||
| open fun findQcItemByCode(code: String): QcItem? { | |||||
| return qcItemRepository.findByCodeAndDeletedIsFalse(code) | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,76 @@ | |||||
| package com.ffii.fpsms.modules.master.web | |||||
| import com.ffii.fpsms.modules.master.entity.QcItem | |||||
| import com.ffii.fpsms.modules.master.entity.QcItemRepository | |||||
| import com.ffii.fpsms.modules.master.service.QcItemService | |||||
| import com.ffii.fpsms.modules.master.web.models.SaveQcItemRequest | |||||
| import com.ffii.fpsms.modules.master.web.models.SaveQcItemResponse | |||||
| import jakarta.validation.Valid | |||||
| import org.springframework.web.bind.annotation.GetMapping | |||||
| import org.springframework.web.bind.annotation.PostMapping | |||||
| import org.springframework.web.bind.annotation.RequestBody | |||||
| import org.springframework.web.bind.annotation.RequestMapping | |||||
| import org.springframework.web.bind.annotation.RestController | |||||
| import kotlin.reflect.KClass | |||||
| import kotlin.reflect.KProperty | |||||
| import kotlin.reflect.KParameter | |||||
| import kotlin.reflect.KTypeParameter | |||||
| import kotlin.reflect.typeOf | |||||
| @RestController | |||||
| @RequestMapping("/qcItems") | |||||
| class QcItemController( | |||||
| private val qcItemService: QcItemService, | |||||
| private val qcItemRepository: QcItemRepository, | |||||
| ) { | |||||
| @GetMapping | |||||
| fun allQcItems(): List<QcItem> { | |||||
| return qcItemService.allQcItems() | |||||
| } | |||||
| @PostMapping("/save") | |||||
| fun saveQcItem(@Valid @RequestBody request: SaveQcItemRequest): SaveQcItemResponse { | |||||
| // val qcItemProperties = QcItem::class.members.filterIsInstance<KProperty<QcItem>>() | |||||
| val errors = mutableMapOf<String, String>() | |||||
| val id = request.id | |||||
| val qcItem = if (id != null) qcItemRepository.findById(id).orElseThrow() else QcItem() | |||||
| // check duplicated code | |||||
| val duplicateQcItem = qcItemService.findQcItemByCode(request.code) | |||||
| if (duplicateQcItem != null && duplicateQcItem.id != qcItem.id) { | |||||
| errors["code"] = "Code is duplicated" | |||||
| } | |||||
| if (errors.isNotEmpty()) { | |||||
| request.let { | |||||
| SaveQcItemResponse( | |||||
| id = it.id, | |||||
| code = it.code, | |||||
| name = it.name, | |||||
| description = it.description, | |||||
| errors = errors | |||||
| ) | |||||
| } | |||||
| } | |||||
| // Save Qc Item | |||||
| qcItem.apply { | |||||
| code = request.code | |||||
| name = request.name | |||||
| description = request.description | |||||
| } | |||||
| val savedQcItem = qcItemRepository.save(qcItem) | |||||
| return savedQcItem.let { | |||||
| SaveQcItemResponse( | |||||
| id = it.id, | |||||
| code = it.code, | |||||
| name = it.name, | |||||
| description = it.description, | |||||
| errors = null | |||||
| ) | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,12 @@ | |||||
| package com.ffii.fpsms.modules.master.web.models | |||||
| import jakarta.validation.constraints.NotBlank | |||||
| data class SaveQcItemRequest( | |||||
| val id: Long?, | |||||
| @field:NotBlank(message = "Code cannot be empty") | |||||
| val code: String, | |||||
| @field:NotBlank(message = "Name cannot be empty") | |||||
| val name: String, | |||||
| val description: String?, | |||||
| ) | |||||
| @@ -0,0 +1,9 @@ | |||||
| package com.ffii.fpsms.modules.master.web.models | |||||
| data class SaveQcItemResponse( | |||||
| val id: Long?, | |||||
| val code: String?, | |||||
| val name: String?, | |||||
| val description: String?, | |||||
| val errors: MutableMap<String, String>? | |||||
| ) | |||||
| @@ -0,0 +1,18 @@ | |||||
| --liquibase formatted sql | |||||
| --changeset cyril:qc_item | |||||
| CREATE TABLE `qc_item` | |||||
| ( | |||||
| `id` INT NOT NULL AUTO_INCREMENT, | |||||
| `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||||
| `createdBy` VARCHAR(30) NULL DEFAULT NULL, | |||||
| `version` INT NOT NULL DEFAULT '0', | |||||
| `modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||||
| `modifiedBy` VARCHAR(30) NULL DEFAULT NULL, | |||||
| `deleted` TINYINT(1) NOT NULL DEFAULT '0', | |||||
| `code` VARCHAR(30) NOT NULL, | |||||
| `name` VARCHAR(30) NOT NULL, | |||||
| `description` VARCHAR(100) NULL, | |||||
| `systemInput` TINYINT(1) NOT NULL, | |||||
| PRIMARY KEY (`id`) | |||||
| ); | |||||