Sfoglia il codice sorgente

open new column, product porcess and created job order

master
CANCERYS\kw093 1 giorno fa
parent
commit
a2a01c2f02
13 ha cambiato i file con 196 aggiunte e 25 eliminazioni
  1. +3
    -1
      src/main/java/com/ffii/fpsms/modules/jobOrder/entity/projections/JobOrderInfo.kt
  2. +2
    -1
      src/main/java/com/ffii/fpsms/modules/jobOrder/enums/JobOrderEnum.kt
  3. +70
    -8
      src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoPickOrderService.kt
  4. +59
    -6
      src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt
  5. +11
    -1
      src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt
  6. +20
    -1
      src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/CreateJobOrderRequest.kt
  7. +3
    -2
      src/main/java/com/ffii/fpsms/modules/productProcess/entity/projections/ProductProcessInfo.kt
  8. +1
    -1
      src/main/java/com/ffii/fpsms/modules/productProcess/service/ProductProcessService.kt
  9. +7
    -3
      src/main/java/com/ffii/fpsms/modules/productProcess/web/ProductProcessController.kt
  10. +3
    -1
      src/main/java/com/ffii/fpsms/modules/productProcess/web/model/SaveProductProcessRequest.kt
  11. +7
    -0
      src/main/resources/db/changelog/changes/20251224_01_Enson/01_alter_table.sql
  12. +5
    -0
      src/main/resources/db/changelog/changes/20251224_01_Enson/02_alter_table.sql
  13. +5
    -0
      src/main/resources/db/changelog/changes/20251230_01_Enson/01_alter_table.sql

+ 3
- 1
src/main/java/com/ffii/fpsms/modules/jobOrder/entity/projections/JobOrderInfo.kt Vedi File

@@ -35,7 +35,8 @@ interface JobOrderInfo {
// @get:Value("#{target.bom.item.itemUoms.^[salesUnit == true && deleted == false]?.uom}")
//// @get:Value("#{target.bom.item.itemUoms.^[salesUnit == true && deleted == false]?.uom.udfudesc}")
// val uom: UomConversion;

@get:Value("#{target.productProcess?.productionPriority}")
val productionPriority: Int?;
@get:Value("#{target.status.value}")
val status: String;

@@ -62,6 +63,7 @@ data class JobOrderInfoWithTypeName(
val insufficientCount: Int?,
val silHandlerId: Long?,
val planStart: LocalDateTime?,
val productionPriority: Int?,
val status: String,
val jobTypeId: Long?,
val jobTypeName: String?


+ 2
- 1
src/main/java/com/ffii/fpsms/modules/jobOrder/enums/JobOrderEnum.kt Vedi File

@@ -3,8 +3,9 @@ package com.ffii.fpsms.modules.jobOrder.enums
enum class JobOrderStatus(val value: String) {
PLANNING("planning"),
PENDING("pending"),
PROCESSING("processing"),
PACKAGING("packaging"),
PROCESSING("processing"),
PENDING_QC("pendingQC"),
STORING("storing"),
COMPLETED("completed")
}

+ 70
- 8
src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoPickOrderService.kt Vedi File

@@ -2050,34 +2050,96 @@ open fun getJobOrderLotsHierarchicalByPickOrderId(pickOrderId: Long): JobOrderLo
}
}

open fun updateHandledByForItem(pickOrderId: Long, itemId: Long, userId: Long): JoPickOrder? {
open fun updateHandledByForItem(pickOrderId: Long, itemId: Long, userId: Long): MessageResponse {
val joPickOrderOpt = joPickOrderRepository.findByPickOrderIdAndItemId(pickOrderId, itemId)
if (joPickOrderOpt.isEmpty) {
println("⚠️ JoPickOrder not found for pickOrderId: $pickOrderId, itemId: $itemId")
return null
return MessageResponse(
id = 0,
code = "404",
name = "Not Found",
type = "error",
message = "JoPickOrder not found",
errorPosition = "operator"
)
}
val joPickOrder = joPickOrderOpt.get()
if (userId != null && joPickOrder.handledBy != null) {
val existingOperatorId = joPickOrder.handledBy
val newOperatorId = userId
// 如果不是同一个用户,拒绝更新
if (existingOperatorId != null && existingOperatorId != newOperatorId) {
return MessageResponse(
id = joPickOrder.id,
code = "409",
name = "Conflict",
type = "error",
message = "This pick order is already assigned to another user",
errorPosition = "operator"
)
}
}
joPickOrder.handledBy = userId
joPickOrderRepository.save(joPickOrder)
// Don't update other fields - only handledBy
return joPickOrderRepository.save(joPickOrder)
return MessageResponse(
id = joPickOrder.id,
code = null,
name = null,
type = null,
message = "Pick order handled by updated",
errorPosition = null
)
}

open fun updateRecordHandledByForItem(pickOrderId: Long, itemId: Long, userId: Long): JoPickOrderRecord? {
open fun updateRecordHandledByForItem(pickOrderId: Long, itemId: Long, userId: Long): MessageResponse {
val joPickOrderRecordOpt = joPickOrderRecordRepository.findByPickOrderIdAndItemId(pickOrderId, itemId)
if (joPickOrderRecordOpt.isEmpty) {
println("⚠️ JoPickOrderRecord not found for pickOrderId: $pickOrderId, itemId: $itemId")
return null
return MessageResponse(
id = 0,
code = "404",
name = "Not Found",
type = "error",
message = "JoPickOrderRecord not found",
errorPosition = "operator"
)
}
val joPickOrderRecord = joPickOrderRecordOpt.get()
if (userId != null && joPickOrderRecord.handledBy != null) {
val existingOperatorId = joPickOrderRecord.handledBy
val newOperatorId = userId
// 如果不是同一个用户,拒绝更新
if (existingOperatorId != null && existingOperatorId != newOperatorId) {
return MessageResponse(
id = joPickOrderRecord.id,
code = "409",
name = "Conflict",
type = "error",
message = "This pick order is already assigned to another user",
errorPosition = "operator"
)
}
}
joPickOrderRecord.handledBy = userId
joPickOrderRecordRepository.save(joPickOrderRecord)
// Don't update other fields - only handledBy
return joPickOrderRecordRepository.save(joPickOrderRecord)
return MessageResponse(
id = joPickOrderRecord.id,
code = null,
name = null,
type = null,
message = "Pick order record handled by updated",
errorPosition = null
)
}
@Transactional(rollbackFor = [Exception::class])
open fun deleteJoPickOrderJobOrderProductProcessPickOrder(jobOrderId: Long): MessageResponse {


+ 59
- 6
src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt Vedi File

@@ -27,8 +27,7 @@ import org.springframework.data.domain.PageRequest
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.math.BigDecimal
import java.time.LocalDate
import java.time.LocalDateTime

import java.time.format.DateTimeFormatter
import kotlin.jvm.optionals.getOrNull
import com.ffii.fpsms.modules.jobOrder.entity.JobTypeRepository
@@ -62,8 +61,10 @@ import com.ffii.fpsms.modules.stock.service.QrContent
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlin.math.exp
import com.ffii.fpsms.modules.productProcess.entity.ProductProcessRepository


import java.time.LocalDate
import java.time.LocalDateTime
@Service
open class JobOrderService(
val jobOrderRepository: JobOrderRepository,
@@ -81,7 +82,8 @@ open class JobOrderService(
private val printerService: PrinterService,
val jobTypeRepository: JobTypeRepository,
val inventoryRepository: InventoryRepository,
val stockInLineRepository: StockInLineRepository
val stockInLineRepository: StockInLineRepository,
val productProcessRepository: ProductProcessRepository
) {

open fun allJobOrdersByPage(request: SearchJobOrderInfoRequest): RecordsRes<JobOrderInfo> {
@@ -176,6 +178,7 @@ open class JobOrderService(
insufficientCount = insufficientCount,
silHandlerId = info.silHandlerId,
planStart = info.planStart,
productionPriority = info.productionPriority,
status = info.status,
jobTypeId = info.jobTypeId,
jobTypeName = info.jobTypeId?.let { jobTypes[it]?.name }
@@ -192,7 +195,7 @@ open class JobOrderService(
val notCompletedPutaway = info.stockInLineStatus != "completed"
jobTypeNameMatch && notCompletedPutaway
}
}.sortedByDescending { it.productionPriority }

// 修复:使用 response.totalElements,这是过滤后的总数
val total = response.totalElements
@@ -749,5 +752,55 @@ open class JobOrderService(
open fun getAllJobTypes(): List<JobTypeResponse> {
return jobTypeRepository.findAll().map { JobTypeResponse(it.id, it.name) }
}

open fun updateJoPlanStart(request: UpdateJoPlanStartRequest): MessageResponse {
val jo = request.id.let { jobOrderRepository.findById(it).getOrNull() } ?: throw NoSuchElementException()
// 将 String 转换为 LocalDateTime
val planStartDateTime = if (request.planStart.isNotBlank()) {
try {
// 支持 ISO 格式: "YYYY-MM-DDTHH:mm:ss" 或 "YYYY-MM-DD"
if (request.planStart.contains("T")) {
LocalDateTime.parse(request.planStart)
} else {
// 如果只有日期,设置为当天的 00:00:00
LocalDate.parse(request.planStart).atStartOfDay()
}
} catch (e: Exception) {
throw BadRequestException("Invalid date format: ${request.planStart}")
}
} else {
null
}
jo.apply {
planStart = planStartDateTime
}
jobOrderRepository.save(jo)
val planStartDate = planStartDateTime?.toLocalDate()
val productProcesses = productProcessRepository.findByJobOrder_Id(jo.id)
productProcesses.forEach { productProcess ->
productProcess.apply {
date = planStartDate
}
productProcessRepository.save(productProcess)
}
return MessageResponse(
id = jo.id,
code = jo.code,
name = jo.bom?.name,
type = null,
message = null,
errorPosition = null,
entity = mapOf("status" to jo.status?.value)
)
}
/*
open fun checkJobOrderCreated(request: CheckJobOrderCreatedRequest): CheckJobOrderCreatedResponse {
val jobOrders = jobOrderRepository.findByBomIdAndDate(request.bomId, request.date)
return CheckJobOrderCreatedResponse(
isCreated = jobOrders.isNotEmpty(),
jobOrders = jobOrders.map { JobOrderBasicInfoResponse(it.id, it.code, it.bom?.name, it.reqQty) }
)
}
*/
}

+ 11
- 1
src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt Vedi File

@@ -99,7 +99,7 @@ class JobOrderController(
}
jobOrderBomMaterialService.createJobOrderBomMaterialsByJoId(jo.id)
jobOrderProcessService.createJobOrderProcessesByJoId(jo.id)
productProcessService.createProductProcessByJobOrderId(jo.id)
productProcessService.createProductProcessByJobOrderId(jo.id, request.productionPriority)
return jo
}
@GetMapping("/all-lots-hierarchical/{userId}")
@@ -306,4 +306,14 @@ fun updateJoPickOrderHandledBy(@Valid @RequestBody request: UpdateJoPickOrderHan
fun deleteJoPickOrderJobOrderProductProcessPickOrder(@PathVariable jobOrderId: Long): MessageResponse {
return joPickOrderService.deleteJoPickOrderJobOrderProductProcessPickOrder(jobOrderId)
}
@PostMapping("/update-jo-plan-start")
fun updateJoPlanStart(@Valid @RequestBody request: UpdateJoPlanStartRequest): MessageResponse {
return jobOrderService.updateJoPlanStart(request)
}
/*
@PostMapping("/checkJobOrderCreated")
fun checkJobOrderCreated(@Valid @RequestBody request: CheckJobOrderCreatedRequest): Boolean {
return jobOrderService.checkJobOrderCreated(request)
}
*/
}

+ 20
- 1
src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/CreateJobOrderRequest.kt Vedi File

@@ -3,7 +3,7 @@ package com.ffii.fpsms.modules.jobOrder.web.model
import com.ffii.fpsms.modules.jobOrder.enums.JobOrderBomMaterialStatus
import java.math.BigDecimal
import java.time.LocalDateTime
import java.time.LocalDate
data class CreateJobOrderRequest (
val bomId: Long?,
val planStart: LocalDateTime? = null,
@@ -15,6 +15,7 @@ data class CreateJobOrderRequest (
val approverId: Long? = null,
val prodScheduleLineId: Long? = null,
val status: String = "planning",
val productionPriority: Int?=50,
)

data class CreateJobOrderBomMaterialRequest (
@@ -130,4 +131,22 @@ data class JobOrderListForPrintQrCodeResponse(
val stockInLineQty: Double,
val stockInLineStatus: String,
val finihedTime: LocalDateTime,
)
data class UpdateJoPlanStartRequest(
val id: Long,
val planStart: String,
)
data class CheckJobOrderCreatedRequest(
val bomId: Long,
val date: LocalDate,
)
data class CheckJobOrderCreatedResponse(
val isCreated: Boolean,
val jobOrders: List<JobOrderInfoResponse>,
)
data class JobOrderInfoResponse(
val jobOrderId: Long,
val code: String,
val itemName: String,
val reqQty: BigDecimal,
)

+ 3
- 2
src/main/java/com/ffii/fpsms/modules/productProcess/entity/projections/ProductProcessInfo.kt Vedi File

@@ -10,9 +10,9 @@ data class ProductProcessInfo(
val id: Long?,
val productProcessCode: String?,
val status: ProductProcessStatus?,
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "MM-dd HH:mm")
val startTime: LocalDateTime?,
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "MM-dd HH:mm")
val endTime: LocalDateTime?,
@JsonFormat(pattern = "yyyy-MM-dd")
val date: LocalDate?,
@@ -23,6 +23,7 @@ data class ProductProcessInfo(
val jobOrderCode: String?,
val jobOrderStatus: String?,
val jobType: String?,
val bomDescription: String?,
val isDark: String?,
val isDense: Int?,
val isFloat: String?,


+ 1
- 1
src/main/java/com/ffii/fpsms/modules/productProcess/service/ProductProcessService.kt Vedi File

@@ -685,7 +685,7 @@ open class ProductProcessService(
}
}

open fun createProductProcessByJobOrderId(jobOrderId: Long): MessageResponse {
open fun createProductProcessByJobOrderId(jobOrderId: Long,productionPriority: Int?): MessageResponse {
val jobOrder = jobOrderRepository.findById(jobOrderId).orElse(null)
val bom = bomRepository.findById(jobOrder?.bom?.id ?: 0L).orElse(null)
// val bom = jobOrder.bom.let { bomRepository.findById(it).orElse(null) }


+ 7
- 3
src/main/java/com/ffii/fpsms/modules/productProcess/web/ProductProcessController.kt Vedi File

@@ -160,9 +160,9 @@ class ProductProcessController(
fun demojoid(@PathVariable joid: Long): List<ProductProcessInfo> {
return productProcessService.productProcessDetailfindbyjoid(joid)
}
@PostMapping("/demo/joid/{joid}")
fun democreate(@PathVariable joid: Long): MessageResponse {
return productProcessService.createProductProcessByJobOrderId(joid)
@PostMapping("/demo/joid/{joid}/{productionPriority}")
fun democreate(@PathVariable joid: Long, @PathVariable productionPriority: Int): MessageResponse {
return productProcessService.createProductProcessByJobOrderId(joid, productionPriority)
}
@PostMapping("/Demo/update")
fun demoupdate(@RequestBody request: UpdateProductProcessLineOperatorIdOrEquipmentIdRequest): MessageResponse {
@@ -213,4 +213,8 @@ class ProductProcessController(
fun updateProductProcessPriority(@PathVariable productProcessId: Long, @PathVariable productionPriority: Int): MessageResponse {
return productProcessService.UpdateProductProcessPriority(productProcessId, productionPriority)
}
@PostMapping("/Demo/ProcessLine/pass/{lineId}")
fun passProductProcessLine(@PathVariable lineId: Long): MessageResponse {
return productProcessService.passProductProcessLine(lineId)
}
}

+ 3
- 1
src/main/java/com/ffii/fpsms/modules/productProcess/web/model/SaveProductProcessRequest.kt Vedi File

@@ -169,13 +169,15 @@ data class AllJoborderProductProcessInfoResponse(
val RequiredQty: Int?,
val Uom: String?,
val jobOrderId: Long?,
val productionPriority: Int?,
val jobOrderCode: String?,
val assignedTo: Long?,
val pickOrderId: Long?,
val pickOrderStatus: String?,
val productProcessLineCount: Int,
val FinishedProductProcessLineCount: Int,
val stockInLineId: Long?,
val stockInLineId: Long?,
val TimeNeedToComplete: Int?,
val lines: List<ProductProcessInfoResponse>
)
data class ProductProcessInfoResponse(


+ 7
- 0
src/main/resources/db/changelog/changes/20251224_01_Enson/01_alter_table.sql Vedi File

@@ -0,0 +1,7 @@
-- liquibase formatted sql
-- changeset Enson:add_column

ALTER TABLE `fpsmsdb`.`bag_lot_line`
CHANGE COLUMN `firstUseDate` `firstUseDate` DATETIME NULL ,
CHANGE COLUMN `lastUseDate` `lastUseDate` DATETIME NULL ,
ADD COLUMN `stockOutLineId` BIGINT NULL AFTER `bagId`;

+ 5
- 0
src/main/resources/db/changelog/changes/20251224_01_Enson/02_alter_table.sql Vedi File

@@ -0,0 +1,5 @@
-- liquibase formatted sql
-- changeset Enson:add_column

ALTER TABLE `fpsmsdb`.`jo_bag_consumption`
ADD COLUMN `stockOutLineId` BIGINT NULL AFTER `jobOrderCode`;

+ 5
- 0
src/main/resources/db/changelog/changes/20251230_01_Enson/01_alter_table.sql Vedi File

@@ -0,0 +1,5 @@
-- liquibase formatted sql
-- changeset Enson:add_column

ALTER TABLE `fpsmsdb`.`productprocess`
ADD COLUMN `submitedBagRecord`TINYINT(1) NULL DEFAULT 0 AFTER `productionPriority`;

Caricamento…
Annulla
Salva