Browse Source

update

master
CANCERYS\kw093 3 months ago
parent
commit
82c3e50a1a
9 changed files with 324 additions and 10 deletions
  1. +3
    -1
      src/main/java/com/ffii/fpsms/modules/master/service/ItemsService.kt
  2. +29
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/entity/PickOrderGroup.kt
  3. +42
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/entity/PickOrderGroupRepository.kt
  4. +15
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/entity/projection/PickOrderGroupInfo.kt
  5. +134
    -6
      src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt
  6. +68
    -3
      src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt
  7. +1
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderResponse.kt
  8. +12
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/SavePickOrderGroupRequest.kt
  9. +20
    -0
      src/main/resources/db/changelog/changes/20250825_01_enson/01_create_pick_order_group.sql

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

@@ -82,11 +82,13 @@ open class ItemsService(
po.targetDate,
po.status,
po.consoCode,
po.assignTo
po.assignTo,
COALESCE(pog.name, 'No Group') as groupName
FROM pick_order po
JOIN pick_order_line pol ON pol.poId = po.id
JOIN items i ON i.id = pol.itemId
LEFT JOIN uom_conversion uc ON uc.id = pol.uomId
LEFT JOIN pick_order_group pog ON pog.pick_order_id = po.id AND pog.deleted = false
LEFT JOIN (
SELECT
il.itemId,


+ 29
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/entity/PickOrderGroup.kt View File

@@ -0,0 +1,29 @@
package com.ffii.fpsms.modules.pickOrder.entity

import com.ffii.core.entity.BaseEntity
import com.ffii.fpsms.modules.user.entity.User
import jakarta.persistence.*
import jakarta.validation.constraints.NotNull
import jakarta.validation.constraints.Size
import java.time.LocalDate

@Entity
@Table(name = "pick_order_group")
open class PickOrderGroup: BaseEntity<Long>() {
@Column(name = "pick_order_id")
open var pickOrderId: Long? = null

@Size(max = 50)
@Column(name = "name")
open var name: String? = null

@Column(name = "target_date")
open var targetDate: LocalDate? = null

@ManyToOne
@JoinColumn(name = "releasedBy", referencedColumnName = "id")
open var releasedBy: User? = null
}

+ 42
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/entity/PickOrderGroupRepository.kt View File

@@ -0,0 +1,42 @@
package com.ffii.fpsms.modules.pickOrder.entity

import com.ffii.core.support.AbstractRepository
import org.springframework.stereotype.Repository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderGroupInfo

@Repository
interface PickOrderGroupRepository : AbstractRepository<PickOrderGroup, Long> {
@Query("""
SELECT pog FROM PickOrderGroup pog
WHERE pog.deleted = false
ORDER BY pog.name DESC
""")
fun findTopByOrderByNameDesc(): PickOrderGroup?
@Query("""
SELECT pog FROM PickOrderGroup pog
WHERE pog.pickOrderId = :pickOrderId
AND pog.deleted = false
""")
fun findByPickOrderIdAndDeletedIsFalse(@Param("pickOrderId") pickOrderId: Long): List<PickOrderGroup>
@Query("""
SELECT pog FROM PickOrderGroup pog
WHERE pog.pickOrderId IN :pickOrderIds
AND pog.deleted = false
""")
fun findByPickOrderIdInAndDeletedIsFalse(@Param("pickOrderIds") pickOrderIds: List<Long>): List<PickOrderGroup>
@Query("""
SELECT pog FROM PickOrderGroup pog
WHERE pog.name = :name
AND pog.deleted = false
""")
fun findByNameAndDeletedIsFalse(@Param("name") name: String): PickOrderGroup?
@Query("""
SELECT pog FROM PickOrderGroup pog
WHERE pog.deleted = false
""")
fun findAllByDeletedIsFalse(): List<PickOrderGroupInfo>
}

+ 15
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/entity/projection/PickOrderGroupInfo.kt View File

@@ -0,0 +1,15 @@
package com.ffii.fpsms.modules.pickOrder.entity.projection

import org.springframework.beans.factory.annotation.Value
import java.time.LocalDate



interface PickOrderGroupInfo {
val id: Long?
val name: String?
val targetDate: LocalDate?
val pickOrderId: Long?


}

+ 134
- 6
src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt View File

@@ -16,6 +16,8 @@ import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository
import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderInfo
import com.ffii.fpsms.modules.pickOrder.enums.PickOrderLineStatus
import com.ffii.fpsms.modules.pickOrder.enums.PickOrderStatus
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderGroup
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderGroupRepository
import com.ffii.fpsms.modules.pickOrder.web.models.*
import com.ffii.fpsms.modules.stock.entity.InventoryLotLineRepository
import com.ffii.fpsms.modules.stock.entity.StockOut
@@ -44,6 +46,7 @@ import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.jvm.optionals.getOrNull
import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderGroupInfo

@Service
open class PickOrderService(
@@ -54,6 +57,7 @@ open class PickOrderService(
private val userService: UserService,
private val stockOutLIneRepository: StockOutLIneRepository,
private val inventoryLotLineRepository: InventoryLotLineRepository,
private val pickOrderGroupRepository: PickOrderGroupRepository,
private val inventoryLotLineService: InventoryLotLineService,
private val inventoryService: InventoryService,
private val stockOutRepository: StockOutRepository,
@@ -152,7 +156,8 @@ open class PickOrderService(

// Get full pick orders with relationships
val fullPickOrders = pickOrderRepository.findAllByIdIn(pickOrderIds)

val groupsByPickOrderId = pickOrderGroupRepository.findByPickOrderIdInAndDeletedIsFalse(pickOrderIds)
.groupBy { it.pickOrderId }
// Get all item IDs
val itemIds = fullPickOrders
.flatMap { it.pickOrderLines }
@@ -191,7 +196,9 @@ open class PickOrderService(
suggestedList = emptyList() // Empty list since you don't need suggestions
)
}

val groupName = po.id?.let { pickOrderId ->
groupsByPickOrderId[pickOrderId]?.firstOrNull()?.name
} ?: "No Group"
GetPickOrderInfo(
id = po.id,
code = po.code,
@@ -199,6 +206,7 @@ open class PickOrderService(
type = po.type?.value,
status = po.status?.value,
assignTo = po.assignTo?.id,
groupName = groupName,
pickOrderLines = pickOrderLineInfos
)
}
@@ -644,6 +652,8 @@ open class PickOrderService(
val one = BigDecimal.ONE
val pos = pickOrderRepository.findAllByIdIn(ids)
println(pos)
val groupsByPickOrderId = pickOrderGroupRepository.findByPickOrderIdInAndDeletedIsFalse(ids)
.groupBy { it.pickOrderId }
// Get Inventory Data
val requiredItems = pos
.flatMap { it.pickOrderLines }
@@ -698,7 +708,9 @@ open class PickOrderService(
)
// }
}

val groupName = po.id?.let { pickOrderId ->
groupsByPickOrderId[pickOrderId]?.firstOrNull()?.name
} ?: "No Group"
// Return
GetPickOrderInfo(
id = po.id,
@@ -707,6 +719,7 @@ open class PickOrderService(
type = po.type?.value,
status = po.status?.value,
assignTo = po.assignTo?.id,
groupName = groupName,
pickOrderLines = releasePickOrderLineInfos
)
}
@@ -873,7 +886,7 @@ open class PickOrderService(
il.lotNo,
il.expiryDate,
w.name as location,
COALESCE(uc.code, 'N/A') as stockUnit,
COALESCE(uc.udfudesc, 'N/A') as stockUnit,
(COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) as availableQty,
spl.qty as requiredQty,
COALESCE(sol.qty, 0) as actualPickQty,
@@ -1092,12 +1105,127 @@ open class PickOrderService(
} else {
return MessageResponse(
id = stockOut.id,
name = stockOut.consoPickOrderCode ?: stockOut.deliveryOrderCode, // 修复:使用 stockOut 而不是 savedStockOut
code = stockOut.consoPickOrderCode ?: stockOut.deliveryOrderCode, // 修复:使用 stockOut 而不是 savedStockOut
name = stockOut.consoPickOrderCode ?: stockOut.deliveryOrderCode,
code = stockOut.consoPickOrderCode ?: stockOut.deliveryOrderCode,
type = stockOut.type,
message = "not completed",
errorPosition = null,
)
}
}

open fun createGroup(name: String, targetDate: LocalDate, pickOrderId: Long?): PickOrderGroup {
val group = PickOrderGroup().apply {
this.name = name
this.targetDate = targetDate
this.pickOrderId = pickOrderId
}
return pickOrderGroupRepository.save(group)
}
fun getGroupsByPickOrderId(pickOrderId: Long): List<PickOrderGroup> {
return pickOrderGroupRepository.findByPickOrderIdAndDeletedIsFalse(pickOrderId)
}

fun getAllGroupsFromDatabase(): List<Map<String, Any>> {
val sql = """
SELECT id, name, target_date, pick_order_id
FROM pick_order_group
WHERE deleted = false
ORDER BY name ASC
""".trimIndent()
return jdbcDao.queryForList(sql, emptyMap<String, Any>())
}

open fun allPickOrdersGroup(): List<PickOrderGroupInfo> {
return pickOrderGroupRepository.findAllByDeletedIsFalse()
}
open fun getLatestGroupNameAndCreate(): MessageResponse {
// Use the working repository method like the old /latest endpoint
val allGroups = allPickOrdersGroup()
val nextGroupName = if (allGroups.isNotEmpty()) {
// Sort by numeric part of the name (A001 -> 1, A006 -> 6)
val latestName = allGroups
.filter { it.name?.startsWith("A") == true }
.maxByOrNull { group ->
group.name?.substring(1)?.toIntOrNull() ?: 0
}?.name ?: "A000"
// Generate next group name
val currentNumber = latestName.substring(1).toIntOrNull() ?: 0
val nextNumber = currentNumber + 1
"A${nextNumber.toString().padStart(3, '0')}"
} else {
"A001" // If no groups exist, return A001
}
// Use the new flexible createNewGroups method
val request = SavePickOrderGroupRequest(
names = listOf(nextGroupName), // Create new group with the generated name
targetDate = null,
pickOrderId = null
)
return createNewGroups(request)
}
fun getLatestGroupName(): String {
// Use allPickOrdersGroup() instead of the failing repository method
val allGroups = allPickOrdersGroup()
return if (allGroups.isNotEmpty()) {
// Sort by numeric part of the name (A001 -> 1, A006 -> 6)
val latestName = allGroups
.filter { it.name?.startsWith("A") == true }
.maxByOrNull { group ->
group.name?.substring(1)?.toIntOrNull() ?: 0
}?.name ?: "A000"
// Generate next group name
val currentNumber = latestName.substring(1).toIntOrNull() ?: 0
val nextNumber = currentNumber + 1
"A${nextNumber.toString().padStart(3, '0')}"
} else {
"A001" // If no groups exist, return A001
}
}
open fun createNewGroups(request: SavePickOrderGroupRequest): MessageResponse {
val updatedGroups = mutableListOf<PickOrderGroup>()
val createdGroups = mutableListOf<PickOrderGroup>()
// Case 1: Update existing groups by IDs
request.groupIds?.forEach { groupId ->
val group = pickOrderGroupRepository.findById(groupId).orElse(null)
if (group != null) {
group.targetDate = request.targetDate
group.pickOrderId = request.pickOrderId
val savedGroup = pickOrderGroupRepository.save(group)
updatedGroups.add(savedGroup)
}
}
// Case 2: Create new groups by names
request.names?.forEach { name ->
val group = PickOrderGroup().apply {
this.name = name
this.targetDate = request.targetDate
this.pickOrderId = request.pickOrderId
}
val savedGroup = pickOrderGroupRepository.save(group)
createdGroups.add(savedGroup)
}
val totalGroups = updatedGroups.size + createdGroups.size
val allGroups = updatedGroups + createdGroups
return MessageResponse(
id = allGroups.firstOrNull()?.id,
name = allGroups.map { it.name ?: "" }.joinToString(", "),
code = "groups_processed",
type = "pick_order_groups",
message = "Updated ${updatedGroups.size} groups and created ${createdGroups.size} groups successfully",
errorPosition = "",
)
}
}

+ 68
- 3
src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt View File

@@ -12,6 +12,7 @@ import com.ffii.fpsms.modules.pickOrder.web.models.ConsoPickOrderRequest
import com.ffii.fpsms.modules.pickOrder.web.models.ConsoPickOrderResponse
import com.ffii.fpsms.modules.pickOrder.web.models.ReleaseConsoPickOrderRequest
import com.ffii.fpsms.modules.pickOrder.web.models.SearchPickOrderRequest
import com.ffii.fpsms.modules.pickOrder.web.models.SavePickOrderGroupRequest
import jakarta.servlet.http.HttpServletRequest
import jakarta.validation.Valid
import org.springframework.data.domain.Page
@@ -29,6 +30,8 @@ import org.springframework.web.bind.annotation.RestController
import java.time.DateTimeException
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.LocalDate
import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderGroupInfo

@RestController
@RequestMapping("/pickOrder")
@@ -45,11 +48,12 @@ class PickOrderController(
fun allPickOrdersByPage(@ModelAttribute request: SearchPickOrderRequest): RecordsRes<PickOrderInfo> {
return pickOrderService.allPickOrdersByPage(request);
}
@GetMapping("/getRecordByPageWithStock")
fun getPickOrdersWithStockBalanceByPage(@ModelAttribute request: SearchPickOrderRequest): RecordsRes<GetPickOrderInfo> {
return pickOrderService.getPickOrdersWithStockBalanceByPage(request);
}

@GetMapping("/getRecordByPage-conso")
fun allConsoPickOrdersByPage(request: HttpServletRequest): RecordsRes<Map<String, Any>> {
val criteriaArgs = CriteriaArgsBuilder.withRequest(request)
@@ -60,9 +64,10 @@ class PickOrderController(
val pageSize = request.getParameter("pageSize")?.toIntOrNull() ?: 10 // Default to 10 if not provided
val pageNum = request.getParameter("pageNum")?.toIntOrNull() ?: 1 // Default to 1 if not provided
val fullList = pickOrderService.getConsoPickOrderList(criteriaArgs)
val paginatedList = PagingUtils.getPaginatedList(fullList,pageSize, pageNum)
val paginatedList = PagingUtils.getPaginatedList(fullList, pageSize, pageNum)
return RecordsRes(paginatedList, fullList.size)
}

@PostMapping("/assign")
fun assignPickOrders(@RequestBody request: Map<String, Any>): MessageResponse {
val pickOrderIds = (request["pickOrderIds"] as List<*>).map { it.toString().toLong() }
@@ -77,6 +82,7 @@ class PickOrderController(
val assignTo = request["assignTo"].toString().toLong()
return pickOrderService.releasePickOrders(pickOrderIds, assignTo)
}

@GetMapping("/get-pickorder-line-byPage")
fun getPickOrderLine(request: HttpServletRequest): RecordsRes<Map<String, Any>> {
val criteriaArgs = CriteriaArgsBuilder.withRequest(request)
@@ -85,7 +91,7 @@ class PickOrderController(
val pageSize = request.getParameter("pageSize")?.toIntOrNull() ?: 10 // Default to 10 if not provided
val pageNum = request.getParameter("pageNum")?.toIntOrNull() ?: 1 // Default to 1 if not provided
val fullList = pickOrderService.getPickOrderLine(criteriaArgs)
val paginatedList = PagingUtils.getPaginatedList(fullList,pageSize, pageNum)
val paginatedList = PagingUtils.getPaginatedList(fullList, pageSize, pageNum)
return RecordsRes(paginatedList, fullList.size)
}

@@ -121,16 +127,19 @@ class PickOrderController(
fun getAllPickOrdersInfo(): GetPickOrderInfoResponse {
return pickOrderService.getAllPickOrdersInfo();
}

@PostMapping("/releaseConso")
fun releaseConsoPickOrderAction(@Valid @RequestBody request: ReleaseConsoPickOrderRequest): ReleasePickOrderInfoResponse {
return pickOrderService.releaseConsoPickOrderAction(request)
}

@PostMapping("/release-assigned")
fun releaseAssignedPickOrders(@RequestBody request: Map<String, Any>): MessageResponse {
val pickOrderIds = (request["pickOrderIds"] as List<*>).map { it.toString().toLong() }
val assignTo = request["assignTo"].toString().toLong()
return pickOrderService.releaseAssignedPickOrders(pickOrderIds, assignTo)
}

// Start Pick Order
@GetMapping("/pickConso/{consoCode}")
fun pickConsoPickOrderInfo(@PathVariable consoCode: String): ReleasePickOrderInfoResponse {
@@ -153,4 +162,60 @@ class PickOrderController(
}


@PostMapping("/groups")
fun createGroup(@RequestBody request: Map<String, Any>): ResponseEntity<Map<String, Any>> {
println("request: $request")
val name = request["name"] as String
val targetDateStr = request["targetDate"] as String
val targetDate = LocalDate.parse(targetDateStr)
val pickOrderId = when (val value = request["pickOrderId"]) {
is Int -> value.toLong()
is Long -> value
is String -> value.toLongOrNull()
else -> null
}
println("name: $name")
println("targetDate: $targetDate")
println("pickOrderId: $pickOrderId")
val group = pickOrderService.createGroup(name, targetDate, pickOrderId)
return ResponseEntity.ok(
mapOf(
"id" to (group.id ?: 0L),
"name" to (group.name ?: ""),
"targetDate" to (group.targetDate?.toString() ?: ""),
"pickOrderId" to (group.pickOrderId ?: 0L)
)
)
//println("Response: $response")
}

@GetMapping("/groups/{pickOrderId}")
fun getGroupsByPickOrder(@PathVariable pickOrderId: Long): ResponseEntity<List<Map<String, Any>>> {
val groups = pickOrderService.getGroupsByPickOrderId(pickOrderId)
val response = groups.map { group ->
mapOf(
"id" to (group.id ?: 0L),
"name" to (group.name ?: ""),
"targetDate" to (group.targetDate?.toString() ?: ""),
"pickOrderId" to (group.pickOrderId ?: 0L)
)
}
return ResponseEntity.ok(response)



}
@GetMapping("/groups/latest")
fun getLatestGroupName(): MessageResponse {
return pickOrderService.getLatestGroupNameAndCreate()
}
@GetMapping("/groups/list")
fun getAllGroups(): List<PickOrderGroupInfo> {
return pickOrderService.allPickOrdersGroup()
}
@PostMapping("/groups/create")
fun createNewGroups(@Valid @RequestBody request: SavePickOrderGroupRequest): MessageResponse {
return pickOrderService.createNewGroups(request)
}

}

+ 1
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderResponse.kt View File

@@ -35,6 +35,7 @@ data class GetPickOrderInfo(
val type: String?,
val status: String?,
val assignTo: Long?,
val groupName: String?,
val pickOrderLines: List<GetPickOrderLineInfo>
)



+ 12
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/SavePickOrderGroupRequest.kt View File

@@ -0,0 +1,12 @@
package com.ffii.fpsms.modules.pickOrder.web.models

import java.time.LocalDate


data class SavePickOrderGroupRequest (
val groupIds: List<Long>? = null,
val names: List<String>? = null,
val targetDate: LocalDate?=null,
val pickOrderId: Long? = null
)


+ 20
- 0
src/main/resources/db/changelog/changes/20250825_01_enson/01_create_pick_order_group.sql View File

@@ -0,0 +1,20 @@
-- liquibase formatted sql
-- changeset cyril:create pick order

CREATE TABLE `pick_order_group`
(
`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',
`pick_order_id` INT ,
`name` VARCHAR(50) NOT NULL UNIQUE,
`target_date` DATE NOT NULL,
`releasedBy` INT NULL,
CONSTRAINT pk_pick_order_group PRIMARY KEY (id),
CONSTRAINT `FK_PICK_ORDER_GROUP_ON_PICK_ORDER_ID` FOREIGN KEY (`pick_order_id`) REFERENCES `pick_order` (`id`),
CONSTRAINT `FK_PICK_ORDER_GROUP_ON_RELEASEDBY` FOREIGN KEY (`releasedBy`) REFERENCES `user` (`id`)
);

Loading…
Cancel
Save