Browse Source

Merge remote-tracking branch 'origin/master'

master
CANCERYS\kw093 1 month ago
parent
commit
034f9c6884
16 changed files with 197 additions and 19 deletions
  1. +6
    -5
      src/main/java/com/ffii/fpsms/config/security/jwt/web/JwtAuthenticationController.java
  2. +31
    -7
      src/main/java/com/ffii/fpsms/modules/master/entity/QcCategory.kt
  3. +23
    -0
      src/main/java/com/ffii/fpsms/modules/master/entity/QcCategoryRepository.kt
  4. +5
    -0
      src/main/java/com/ffii/fpsms/modules/master/entity/QcItemCategory.kt
  5. +3
    -0
      src/main/java/com/ffii/fpsms/modules/master/entity/QcItemCategoryRepository.kt
  6. +13
    -0
      src/main/java/com/ffii/fpsms/modules/master/service/ItemsService.kt
  7. +24
    -1
      src/main/java/com/ffii/fpsms/modules/master/service/QcCategoryService.kt
  8. +12
    -2
      src/main/java/com/ffii/fpsms/modules/master/service/QcItemService.kt
  9. +8
    -3
      src/main/java/com/ffii/fpsms/modules/master/web/QcCategoryController.kt
  10. +16
    -1
      src/main/java/com/ffii/fpsms/modules/master/web/QcItemController.kt
  11. +26
    -0
      src/main/java/com/ffii/fpsms/modules/qc/entity/projection/QcCategoryInfo.kt
  12. +9
    -0
      src/main/resources/db/changelog/changes/20251009_01_kelvinS/01_create_items_qc_category_mapping.sql
  13. +5
    -0
      src/main/resources/db/changelog/changes/20251009_01_kelvinS/02_alter_qc_item_category.sql
  14. +5
    -0
      src/main/resources/db/changelog/changes/20251009_01_kelvinS/03_alter_qc_category.sql
  15. +5
    -0
      src/main/resources/db/changelog/changes/20251009_01_kelvinS/04_alter_items_qc_category_mapping.sql
  16. +6
    -0
      src/main/resources/db/changelog/changes/20251023_02_kelvinS/01_alter_qc_category.sql

+ 6
- 5
src/main/java/com/ffii/fpsms/config/security/jwt/web/JwtAuthenticationController.java View File

@@ -108,16 +108,17 @@ public class JwtAuthenticationController {
}

private ResponseEntity<?> createAuthTokenResponse(JwtRequest authenticationRequest) {
final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
if (userDetails == null) {
// final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
final User user = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
if (user == null) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(new ExceptionResponse(authenticationRequest.getUsername() + " not yet register in the system.", null));
}

final String accessToken = jwtTokenUtil.generateToken(userDetails);
final String refreshToken = jwtTokenUtil.createRefreshToken(userDetails.getUsername()).getToken();
final String accessToken = jwtTokenUtil.generateToken(user);
final String refreshToken = jwtTokenUtil.createRefreshToken(user.getUsername()).getToken();

User user = userRepository.findByName(authenticationRequest.getUsername()).get(0);
// User user = userRepository.findByName(authenticationRequest.getUsername()).get(0);

List<String> abilities = new ArrayList<>();
final Set<SimpleGrantedAuthority> userAuthority = userAuthorityService.getUserAuthority(user);


+ 31
- 7
src/main/java/com/ffii/fpsms/modules/master/entity/QcCategory.kt View File

@@ -1,14 +1,10 @@
package com.ffii.fpsms.modules.master.entity

import com.fasterxml.jackson.annotation.JsonBackReference
import com.fasterxml.jackson.annotation.JsonManagedReference
import com.ffii.core.entity.BaseEntity
import jakarta.persistence.CascadeType
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.JoinColumn
import jakarta.persistence.JoinTable
import jakarta.persistence.OneToMany
import jakarta.persistence.Table
import com.ffii.core.entity.IdEntity
import jakarta.persistence.*
import jakarta.validation.constraints.NotNull

@Entity
@@ -22,6 +18,14 @@ open class QcCategory : BaseEntity<Long>() {
@Column(name = "name")
open var name: String? = null

@NotNull
@Column(name = "description")
open var description: String? = null

@NotNull
@Column(name = "isDefault")
open var isDefault: Boolean = false

// @OneToMany(cascade = [CascadeType.ALL])
// @JoinTable(
// name = "qc_item_category",
@@ -33,4 +37,24 @@ open class QcCategory : BaseEntity<Long>() {
@JsonManagedReference
@OneToMany(mappedBy = "qcCategory", cascade = [CascadeType.ALL], orphanRemoval = true)
open var qcItemCategory: MutableList<QcItemCategory> = mutableListOf()
}

@Entity
@Table(name = "items_qc_category_mapping")
open class ItemsQcCategoryMapping : IdEntity<Long>() {
@NotNull
@Column(name = "itemId")
open var itemId: Long? = null

@NotNull
@Column(name = "qcCategoryId")
open var qcCategoryId: Long? = null

@NotNull
@Column(name = "type")
open var type: String? = null
//
// @ManyToOne(fetch = FetchType.LAZY)
// @JoinColumn(name = "qcCategoryId")
// val qcCategory: QcCategory? = null
}

+ 23
- 0
src/main/java/com/ffii/fpsms/modules/master/entity/QcCategoryRepository.kt View File

@@ -2,6 +2,8 @@ package com.ffii.fpsms.modules.master.entity

import com.ffii.core.support.AbstractRepository
import com.ffii.fpsms.modules.master.entity.projections.QcCategoryCombo
import com.ffii.fpsms.modules.qc.entity.projection.QcCategoryInfo
import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository

@Repository
@@ -9,4 +11,25 @@ interface QcCategoryRepository : AbstractRepository<QcCategory, Long> {
fun findAllByDeletedIsFalse(): List<QcCategory>;

fun findQcCategoryComboByDeletedIsFalse(): List<QcCategoryCombo>;

// @Query(
// value = """
// SELECT qcc.* FROM qc_category qcc
// LEFT JOIN items_qc_category_mapping map ON map.qcCategoryId = qcc.id
// WHERE map.type = :type AND map.itemId = :itemId AND qcc.deleted = false
// ORDER BY qcc.id
// LIMIT 1
// """,
// nativeQuery = true
// )
@Query(
"""
SELECT qcc FROM QcCategory qcc
JOIN ItemsQcCategoryMapping map ON qcc.id = map.qcCategoryId
WHERE map.itemId = :itemId AND map.type = :type AND qcc.deleted = false
"""
)
fun findQcCategoryInfoByItemIdAndType(itemId: Long, type: String): QcCategoryInfo?;
fun findQcCategoryInfoByIsDefault(isDefault: Boolean): QcCategoryInfo?;
// fun findByItemIdAndType(itemId: Long, type: String): QcCategory?;
}

+ 5
- 0
src/main/java/com/ffii/fpsms/modules/master/entity/QcItemCategory.kt View File

@@ -22,7 +22,12 @@ open class QcItemCategory : IdEntity<Long>() {
@JoinColumn(name = "qcItemId")
open var qcItem: QcItem? = null

@NotNull
@Column(name = "order")
open var order: Int = 0

@Size(max = 1000)
@Column(name = "description", length = 1000)
open var description: String? = null

}

+ 3
- 0
src/main/java/com/ffii/fpsms/modules/master/entity/QcItemCategoryRepository.kt View File

@@ -1,8 +1,11 @@
package com.ffii.fpsms.modules.master.entity

import com.ffii.core.support.AbstractRepository
import com.ffii.fpsms.modules.qc.entity.projection.QcCategoryInfo
import com.ffii.fpsms.modules.qc.entity.projection.QcItemInfo
import org.springframework.stereotype.Repository

@Repository
interface QcItemCategoryRepository : AbstractRepository<QcItemCategory, Long> {
fun findAllByQcCategoryId(qcCategoryId : Long): List<QcItemInfo>
}

+ 13
- 0
src/main/java/com/ffii/fpsms/modules/master/service/ItemsService.kt View File

@@ -373,4 +373,17 @@ open class ItemsService(
return jdbcDao.queryForList(sql.toString(), args);
}

open fun getItemsIdWithSameCategoryForQc(args: Map<String, Any>): List<Int> {
val sql = StringBuilder("SELECT"
+ " i.id "
+ " FROM items i "
+ " INNER JOIN items_qc_category_mapping iqcm ON iqcm.itemId = i.id AND iqcm.type = :qcType "
+ " LEFT JOIN qc_category qcc ON qcc.id = iqcm.qcCategoryId "
+ " WHERE i.deleted = false AND qcc.deleted = false"
+ " AND LEFT(i.code, 2) = (SELECT LEFT(code, 2) FROM items WHERE id = :itemId)"
+ " AND i.id != :itemId "
)
return jdbcDao.queryForInts(sql.toString(), args);
}
}

+ 24
- 1
src/main/java/com/ffii/fpsms/modules/master/service/QcCategoryService.kt View File

@@ -4,11 +4,13 @@ import com.ffii.core.support.AbstractBaseEntityService
import com.ffii.fpsms.modules.master.entity.QcCategory
import com.ffii.fpsms.modules.master.entity.QcCategoryRepository
import com.ffii.fpsms.modules.master.entity.projections.QcCategoryCombo
import com.ffii.fpsms.modules.qc.entity.projection.QcCategoryInfo
import org.springframework.stereotype.Service

@Service
open class QcCategoryService(
private val qcCategoryRepository: QcCategoryRepository
private val qcCategoryRepository: QcCategoryRepository,
private val itemsService: ItemsService
) {
open fun allQcCategories(): List<QcCategory> {
return qcCategoryRepository.findAllByDeletedIsFalse()
@@ -17,4 +19,25 @@ open class QcCategoryService(
open fun getQcCategoryCombo(): List<QcCategoryCombo> {
return qcCategoryRepository.findQcCategoryComboByDeletedIsFalse();
}

open fun getQcCategoryInfoByMapping(itemId : Long, type: String): QcCategoryInfo? {
var result = qcCategoryRepository.findQcCategoryInfoByItemIdAndType(itemId, type)
if (result == null) { // Temporarily fix for missing QC template (Auto find template from similar items)
val args = mapOf(
"itemId" to itemId,
"qcType" to type
)
val similarItemIds = itemsService.getItemsIdWithSameCategoryForQc(args);

// Comment the lines below to disable auto matching QC from similar items
result = if (similarItemIds.isNotEmpty())
qcCategoryRepository.findQcCategoryInfoByItemIdAndType(similarItemIds[0].toLong(), type)
else null
//
if (result == null) { // Use Default Template
result = qcCategoryRepository.findQcCategoryInfoByIsDefault(true)
}
}
return result;
}
}

+ 12
- 2
src/main/java/com/ffii/fpsms/modules/master/service/QcItemService.kt View File

@@ -1,11 +1,14 @@
package com.ffii.fpsms.modules.master.service

import com.ffii.core.support.AbstractBaseEntityService
import com.ffii.core.support.JdbcDao
import com.ffii.core.exception.NotFoundException
import com.ffii.fpsms.modules.master.entity.QcCategoryRepository
import com.ffii.fpsms.modules.master.entity.QcItem
import com.ffii.fpsms.modules.master.entity.QcItemCategoryRepository
import com.ffii.fpsms.modules.master.entity.QcItemRepository
import com.ffii.fpsms.modules.master.web.models.SaveQcItemRequest
import com.ffii.fpsms.modules.master.web.models.SaveQcItemResponse
import com.ffii.fpsms.modules.qc.entity.projection.QcCategoryInfo
import com.ffii.fpsms.modules.qc.entity.projection.QcItemInfo
import jakarta.validation.Valid
import org.springframework.stereotype.Service
import org.springframework.web.bind.annotation.RequestBody
@@ -13,6 +16,8 @@ import org.springframework.web.bind.annotation.RequestBody
@Service
open class QcItemService(
private val qcItemRepository: QcItemRepository,
private val qcCategoryRepository: QcCategoryRepository,
private val qcItemCategoryRepository: QcItemCategoryRepository,
) {
open fun allQcItems(): List<QcItem> {
return qcItemRepository.findAllByDeletedIsFalse()
@@ -26,6 +31,11 @@ open class QcItemService(
return qcItemRepository.findByIdAndDeletedIsFalse(id)
}

open fun findQcItemsByTemplate(itemId: Long, type: String): List<QcItemInfo>? {
val qcCategoryInfo = qcCategoryRepository.findQcCategoryInfoByItemIdAndType(itemId, type) ?: throw NotFoundException()
return qcItemCategoryRepository.findAllByQcCategoryId(qcCategoryInfo.id)
}

open fun markDeleted(id: Long): List<QcItem> {
val qcItem = qcItemRepository.findById(id).orElseThrow().apply {
deleted = true


+ 8
- 3
src/main/java/com/ffii/fpsms/modules/master/web/QcCategoryController.kt View File

@@ -1,11 +1,11 @@
package com.ffii.fpsms.modules.master.web

import com.ffii.core.exception.NotFoundException
import com.ffii.fpsms.modules.master.entity.QcCategory
import com.ffii.fpsms.modules.master.entity.projections.QcCategoryCombo
import com.ffii.fpsms.modules.master.service.QcCategoryService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import com.ffii.fpsms.modules.qc.entity.projection.QcCategoryInfo
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/qcCategories")
@@ -21,4 +21,9 @@ class QcCategoryController(
fun getQcCategoryCombo(): List<QcCategoryCombo> {
return qcCategoryService.getQcCategoryCombo();
}

@GetMapping("/items")
fun getQcCategoryByTemplate(@RequestParam itemId: Long, @RequestParam(defaultValue = "IQC") type: String): QcCategoryInfo {
return qcCategoryService.getQcCategoryInfoByMapping(itemId, type) ?: throw NotFoundException()
}
}

+ 16
- 1
src/main/java/com/ffii/fpsms/modules/master/web/QcItemController.kt View File

@@ -7,7 +7,10 @@ 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 com.ffii.fpsms.modules.qc.entity.projection.QcCategoryInfo
import com.ffii.fpsms.modules.qc.entity.projection.QcItemInfo
import jakarta.validation.Valid
import jakarta.validation.constraints.NotBlank
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.*
@@ -37,8 +40,20 @@ class QcItemController(
return qcItemService.findQcItemById(id) ?: throw NotFoundException()
}

@GetMapping("/template")
fun qcItemsByTemplate(@RequestParam itemId: Long, @RequestParam(defaultValue = "IQC") type: String): List<QcItemInfo> {
return qcItemService.findQcItemsByTemplate(itemId, type) ?: throw NotFoundException()
}

@PostMapping("/save")
fun saveQcItem(@Valid @RequestBody request: SaveQcItemRequest): SaveQcItemResponse {
return qcItemService.saveQcItem(request)
}
}
}

data class GetQcItemRequest(
@field:NotBlank(message = "Item Id cannot be empty")
val itemId: Long,
@field:NotBlank(message = "Type cannot be empty")
val type: String,
)

+ 26
- 0
src/main/java/com/ffii/fpsms/modules/qc/entity/projection/QcCategoryInfo.kt View File

@@ -0,0 +1,26 @@
package com.ffii.fpsms.modules.qc.entity.projection

import com.ffii.fpsms.modules.master.entity.QcItemCategory
import org.springframework.beans.factory.annotation.Value

interface QcCategoryInfo {
val id: Long
val code: String
val name: String?
val description: String?
@get:Value("#{target.qcItemCategory}")
var qcItems: List<QcItemInfo>
}

interface QcItemInfo {
val id: Long
val order: Int
@get:Value("#{target.qcItem.id}")
val qcItemId: Long
@get:Value("#{target.qcItem.code}")
val code: String
@get:Value("#{target.qcItem.name}")
val name: String?
@get:Value("#{target.qcItem.description}")
val description: String?
}

+ 9
- 0
src/main/resources/db/changelog/changes/20251009_01_kelvinS/01_create_items_qc_category_mapping.sql View File

@@ -0,0 +1,9 @@
-- liquibase formatted sql
-- changeset kelvinS:create items qc category mapping table

CREATE TABLE `items_qc_category_mapping` (
`id` INT NOT NULL,
`itemId` INT NOT NULL,
`qcCategoryId` INT NOT NULL,
`type` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`));

+ 5
- 0
src/main/resources/db/changelog/changes/20251009_01_kelvinS/02_alter_qc_item_category.sql View File

@@ -0,0 +1,5 @@
-- liquibase formatted sql
-- changeset kelvinS:alter qc item category table

ALTER TABLE `qc_item_category`
ADD COLUMN `order` INT NOT NULL AFTER `qcCategoryId`;

+ 5
- 0
src/main/resources/db/changelog/changes/20251009_01_kelvinS/03_alter_qc_category.sql View File

@@ -0,0 +1,5 @@
-- liquibase formatted sql
-- changeset kelvinS:alter qc category table

ALTER TABLE `qc_category`
ADD COLUMN `description` VARCHAR(255) NULL AFTER `name`;

+ 5
- 0
src/main/resources/db/changelog/changes/20251009_01_kelvinS/04_alter_items_qc_category_mapping.sql View File

@@ -0,0 +1,5 @@
-- liquibase formatted sql
-- changeset kelvinS:alter item qc category mapping table

ALTER TABLE `items_qc_category_mapping`
CHANGE COLUMN `id` `id` INT NOT NULL AUTO_INCREMENT ;

+ 6
- 0
src/main/resources/db/changelog/changes/20251023_02_kelvinS/01_alter_qc_category.sql View File

@@ -0,0 +1,6 @@
-- liquibase formatted sql
-- changeset kelvinS:alter qc category table

ALTER TABLE `qc_category`
ADD COLUMN `isDefault` TINYINT(1) NOT NULL DEFAULT '0' AFTER `deleted`,
CHANGE COLUMN `name` `name` VARCHAR(255) NOT NULL ;

Loading…
Cancel
Save