diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrder.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrder.kt index 9d260d5..ae1e574 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrder.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrder.kt @@ -2,6 +2,7 @@ package com.ffii.fpsms.modules.jobOrder.entity import com.ffii.core.entity.BaseEntity import com.ffii.fpsms.modules.master.entity.Bom +import com.ffii.fpsms.modules.master.entity.ProductionScheduleLine import com.ffii.fpsms.modules.user.entity.User import jakarta.persistence.* import jakarta.validation.constraints.NotNull @@ -58,8 +59,8 @@ open class JobOrder : BaseEntity() { @JoinColumn(name = "approverId", referencedColumnName = "id") open var approver: User? = null - // @ManyToOne -// @JoinColumn(name = "jobPlanningLogId") - @Column(name = "prodScheduleLineId") - open var prodScheduleLineId: Long? = null + @OneToOne + @JoinColumn(name = "prodScheduleLineId") +// @Column(name = "prodScheduleLineId") + open var prodScheduleLine: ProductionScheduleLine? = null } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderMaterial.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderBomMaterial.kt similarity index 50% rename from src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderMaterial.kt rename to src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderBomMaterial.kt index a634f1e..45ecf90 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderMaterial.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderBomMaterial.kt @@ -1,21 +1,23 @@ package com.ffii.fpsms.modules.jobOrder.entity +import com.fasterxml.jackson.annotation.JsonBackReference import com.ffii.core.entity.BaseEntity import com.ffii.fpsms.modules.master.entity.Items import com.ffii.fpsms.modules.master.entity.UomConversion import com.ffii.fpsms.modules.stock.entity.InventoryLotLine +import com.ffii.fpsms.modules.stock.entity.SuggestedPickLot import jakarta.persistence.* import jakarta.validation.constraints.NotNull +import jakarta.validation.constraints.Size import java.math.BigDecimal @Entity -@Table(name = "job_order_material") -open class JobOrderMaterial : BaseEntity() { - +@Table(name = "job_order_bom_material") +open class JobOrderBomMaterial : BaseEntity() { @NotNull @ManyToOne - @JoinColumn(name = "jopId", nullable = false) - open var jop: JobOrderProcess? = null + @JoinColumn(name = "jobOrderId", nullable = false) + open var jobOrder: JobOrder? = null @NotNull @ManyToOne @@ -23,8 +25,8 @@ open class JobOrderMaterial : BaseEntity() { open var item: Items? = null @NotNull - @Column(name = "qty", nullable = false, precision = 14, scale = 2) - open var qty: BigDecimal? = null + @Column(name = "reqQty", nullable = false, precision = 14, scale = 2) + open var reqQty: BigDecimal? = null @NotNull @ManyToOne @@ -32,11 +34,11 @@ open class JobOrderMaterial : BaseEntity() { open var uom: UomConversion? = null @ManyToOne - @JoinColumn(name = "inventoryLotLineId") - open var inventoryLotLine: InventoryLotLine? = null + @JoinColumn(name = "suggestedPickLotId") + open var suggestedPickLot: SuggestedPickLot? = null + @Size(max = 255) @NotNull - @ManyToOne - @JoinColumn(name = "joProcessDetailId", nullable = false) - open var joProcessDetail: JobOrderProcessDetail? = null + @Column(name = "status", nullable = false) + open var status: String? = null } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderMaterialRepository.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderBomMaterialRepository.kt similarity index 63% rename from src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderMaterialRepository.kt rename to src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderBomMaterialRepository.kt index 11137ac..825a1f2 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderMaterialRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderBomMaterialRepository.kt @@ -4,5 +4,5 @@ import com.ffii.core.support.AbstractRepository import org.springframework.stereotype.Repository @Repository -interface JobOrderMaterialRepository : AbstractRepository { +interface JobOrderBomMaterialRepository : AbstractRepository { } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderProcess.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderProcess.kt index 4b6d817..5b33016 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderProcess.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderProcess.kt @@ -11,12 +11,12 @@ import java.time.LocalDateTime @Table(name = "job_order_process") open class JobOrderProcess : BaseEntity() { @NotNull - @ManyToOne(fetch = FetchType.LAZY, optional = false) + @ManyToOne @JoinColumn(name = "joId", nullable = false) open var jo: JobOrder? = null @NotNull - @ManyToOne(fetch = FetchType.LAZY, optional = false) + @ManyToOne @JoinColumn(name = "processId", nullable = false) open var process: Process? = null diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderRepository.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderRepository.kt index 4dc9510..64b73e0 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/entity/JobOrderRepository.kt @@ -1,8 +1,13 @@ package com.ffii.fpsms.modules.jobOrder.entity import com.ffii.core.support.AbstractRepository +import org.springframework.data.jpa.repository.Query import org.springframework.stereotype.Repository @Repository interface JobOrderRepository : AbstractRepository { + @Query(""" + select jo.code from JobOrder jo where jo.code like :prefix% order by jo.code desc limit 1 + """) + fun findLatestCodeByPrefix(prefix: String): String? } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderBomMaterialService.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderBomMaterialService.kt new file mode 100644 index 0000000..f72b8f9 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderBomMaterialService.kt @@ -0,0 +1,45 @@ +package com.ffii.fpsms.modules.jobOrder.service + +import com.ffii.fpsms.modules.jobOrder.entity.JobOrderBomMaterial +import com.ffii.fpsms.modules.jobOrder.entity.JobOrderBomMaterialRepository +import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository +import com.ffii.fpsms.modules.jobOrder.web.model.CreateJobOrderBomMaterialRequest +import com.ffii.fpsms.modules.master.entity.ItemsRepository +import com.ffii.fpsms.modules.master.entity.UomConversionRepository +import com.ffii.fpsms.modules.master.web.models.MessageResponse +import org.springframework.stereotype.Service +import kotlin.jvm.optionals.getOrNull + +@Service +open class JobOrderBomMaterialService( + val jobOrderBomMaterialRepository: JobOrderBomMaterialRepository, private val jobOrderRepository: JobOrderRepository, + private val itemsRepository: ItemsRepository, + private val uomConversionRepository: UomConversionRepository +) { + fun createJobOrderBomMaterials(request: List): MessageResponse { + val joBomMaterials = request.map { req -> + val jo = req.joId?.let { jobOrderRepository.findById(it).getOrNull() } + val item = req.itemId?.let { itemsRepository.findById(it).getOrNull() } + val uom = req.uomId?.let { uomConversionRepository.findById(it).getOrNull() } + + JobOrderBomMaterial().apply { + jobOrder = jo + this.item = item + reqQty = req.reqQty + this.uom = uom + status = req.status + } + } + + jobOrderBomMaterialRepository.saveAll(joBomMaterials) + + return MessageResponse( + id = null, + name = null, + code = null, + type = null, + message = "Success", + errorPosition = null + ) + } +} \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderProcessService.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderProcessService.kt index 4b109a2..a60c647 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderProcessService.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderProcessService.kt @@ -7,8 +7,11 @@ import com.ffii.core.support.JdbcDao import com.ffii.fpsms.m18.entity.M18DataLogRepository import com.ffii.fpsms.modules.jobOrder.entity.JobOrderProcess import com.ffii.fpsms.modules.jobOrder.entity.JobOrderProcessRepository +import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository +import com.ffii.fpsms.modules.jobOrder.web.model.CreateJobOrderProcessRequest import com.ffii.fpsms.modules.jobOrder.web.model.MachineRequest import com.ffii.fpsms.modules.jobOrder.web.model.OperatorResponse +import com.ffii.fpsms.modules.master.entity.ProcessRepository import com.ffii.fpsms.modules.master.entity.ShopRepository import com.ffii.fpsms.modules.master.service.CurrencyService import com.ffii.fpsms.modules.master.service.ShopService @@ -45,9 +48,36 @@ import kotlin.jvm.optionals.getOrNull open class JobOrderProcessService( private val jdbcDao: JdbcDao, private val jobOrderProcessRepository: JobOrderProcessRepository, - private val userRepository: UserRepository + private val userRepository: UserRepository, private val processRepository: ProcessRepository, + private val jobOrderRepository: JobOrderRepository, ) : AbstractBaseEntityService(jdbcDao, jobOrderProcessRepository) { + open fun createJobOrderProcesses(request: List): MessageResponse{ + val joProcesses = request.map { req -> + val jo = req.joId?.let { jobOrderRepository.findById(it).getOrNull() } + val process = req.processId?.let { processRepository.findById(it).getOrNull() } + + JobOrderProcess().apply { + this.jo = jo + this.process = process + status = req.status + seqNo = req.seqNo + remarks = req.remarks + } + } + + jobOrderProcessRepository.saveAll(joProcesses) + + return MessageResponse( + id = null, + name = null, + code = null, + type = null, + message = "Success", + errorPosition = null + ) + } + open fun isOperatorExist(request: OperatorRequest): MessageResponse{ val User = userRepository.findByUsernameAndDeletedFalse(request.username) diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt new file mode 100644 index 0000000..1fa69a1 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt @@ -0,0 +1,75 @@ +package com.ffii.fpsms.modules.jobOrder.service + +import com.ffii.fpsms.modules.jobOrder.entity.JobOrder +import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository +import com.ffii.fpsms.modules.jobOrder.web.model.CreateJobOrderRequest +import com.ffii.fpsms.modules.master.entity.ProductionScheduleLineRepository +import com.ffii.fpsms.modules.master.service.BomService +import com.ffii.fpsms.modules.master.web.models.MessageResponse +import com.ffii.fpsms.modules.user.service.UserService +import org.springframework.stereotype.Service +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter +import kotlin.jvm.optionals.getOrNull + +@Service +open class JobOrderService( + val jobOrderRepository: JobOrderRepository, + val bomService: BomService, + val userService: UserService, + val productionScheduleLineRepository: ProductionScheduleLineRepository, +) { + open fun assignJobNo(): String { + val suffixFormat = "%03d" + val pattern = "yyyyMMdd" + val formatter = DateTimeFormatter.ofPattern(pattern) + + val prefix = "JO" + val midfix = LocalDate.now().format(formatter) + val suffix = String.format(suffixFormat, 1) + + val latestCode = jobOrderRepository.findLatestCodeByPrefix("${prefix}-${midfix}") + if (latestCode != null) { + val splitLatestCode = latestCode.split("-") + if (splitLatestCode.size > 2) { + val latestNo = splitLatestCode[2].toInt() + return listOf(prefix, midfix, String.format(suffixFormat, latestNo + 1)).joinToString("-") + } + } + + return listOf(prefix, midfix, suffix).joinToString("-") + } + + open fun createJobOrder(request: CreateJobOrderRequest): MessageResponse { + val jo = JobOrder() + val bom = request.bomId?.let { bomService.findById(it) } + val approver = request.approverId?.let { userService.find(it).getOrNull() } + val prodScheduleLine = request.prodScheduleLineId?.let { productionScheduleLineRepository.findById(it).getOrNull() } + val code = assignJobNo() + + jo.apply { + this.code = code + this.bom = bom + //TODO: planStart & planEnd + planStart = LocalDateTime.now() + planEnd = LocalDateTime.now() + reqQty = request.reqQty + status = request.status + type = request.type + this.approver = approver + this.prodScheduleLine = prodScheduleLine + } + + val savedJo = jobOrderRepository.saveAndFlush(jo); + + return MessageResponse( + id = savedJo.id, + name = null, + code = savedJo.code, + type = savedJo.type, + message = "Success", + errorPosition = null + ) + } +} \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/CreateJobOrderRequest.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/CreateJobOrderRequest.kt new file mode 100644 index 0000000..2ca6a14 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/CreateJobOrderRequest.kt @@ -0,0 +1,31 @@ +package com.ffii.fpsms.modules.jobOrder.web.model + +import java.math.BigDecimal +import java.time.LocalDateTime + +data class CreateJobOrderRequest ( + val bomId: Long?, + val planStart: LocalDateTime? = null, + val planEnd: LocalDateTime? = null, + val reqQty: BigDecimal?, + val type: String? = "detailed", + val approverId: Long?, + val prodScheduleLineId: Long?, + val status: String = "planning", +) + +data class CreateJobOrderBomMaterialRequest ( + val joId: Long?, + val itemId: Long?, + val reqQty: BigDecimal?, + val uomId: Long?, + val status: String = "pending", +) + +data class CreateJobOrderProcessRequest ( + val joId: Long?, + val processId: Long?, + val seqNo: Long?, + val remarks: String? = null, + val status: String = "pending", +) \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt index 71e41a3..c11fb85 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt @@ -61,6 +61,10 @@ open class Bom : BaseEntity() { @OneToMany(mappedBy = "bom", cascade = [CascadeType.ALL], orphanRemoval = true) open var bomMaterials: MutableList = mutableListOf() + @JsonManagedReference + @OneToMany(mappedBy = "bom", cascade = [CascadeType.ALL], orphanRemoval = true) + open var bomProcesses: MutableList = mutableListOf() + @Column(name = "m18Id") open var m18Id: Long? = null diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/BomRepository.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/BomRepository.kt index 4931678..79b0a68 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/BomRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/BomRepository.kt @@ -11,4 +11,6 @@ interface BomRepository : AbstractRepository { fun findByIdAndDeletedIsFalse(id: Serializable): Bom? fun findByM18IdAndDeletedIsFalse(m18Id: Long): Bom? + + fun findByItemIdAndDeletedIsFalse(itemId: Serializable): Bom? } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/ProductionScheduleRepository.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/ProductionScheduleRepository.kt index bfd0543..724b12b 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/ProductionScheduleRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/ProductionScheduleRepository.kt @@ -2,6 +2,7 @@ package com.ffii.fpsms.modules.master.entity import com.ffii.core.support.AbstractRepository import com.ffii.fpsms.modules.master.entity.projections.DetailedProdScheduleWithLine +import com.ffii.fpsms.modules.master.entity.projections.DetailedProdScheduleWithLineWithJsonString import com.ffii.fpsms.modules.master.entity.projections.ProdScheduleInfo import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable @@ -81,29 +82,39 @@ interface ProductionScheduleRepository : AbstractRepository + fun findDetailedProdScheduleWithLine(id: Long): DetailedProdScheduleWithLineWithJsonString? } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/projections/ProdScheduleInfo.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/projections/ProdScheduleInfo.kt index 17e104a..149567e 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/projections/ProdScheduleInfo.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/projections/ProdScheduleInfo.kt @@ -15,7 +15,16 @@ interface ProdScheduleInfo { val type: String? } // Detailed Production Schedule With Line -data class DetailedProdScheduleWithLine( +interface DetailedProdScheduleWithLineWithJsonString { + val id: Long? + val scheduleAt: LocalDateTime? + val totalEstProdCount: BigDecimal? + val totalFGType: Long? +// val prodScheduleLines: List? + val prodScheduleLines: String? +} + +data class DetailedProdScheduleWithLine ( val id: Long?, val scheduleAt: LocalDateTime?, val totalEstProdCount: BigDecimal?, @@ -32,7 +41,7 @@ data class DetailedProdScheduleLineInfo( val type: String?, val demandQty: BigDecimal?, val prodTimeInMinute: List?, - val priority: BigDecimal?, + val priority: BigDecimal? ) data class DetailedProdScheduleLineBomMaterial ( @@ -46,7 +55,7 @@ data class DetailedProdScheduleLineBomMaterial ( data class DetailedProdScheduleLineProdTime ( val equipName: String?, - val minutes: BigDecimal?, + val totalMinutes: BigDecimal? ) // Rough Production Schedule With Line diff --git a/src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt b/src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt index 5fdfd99..c970db8 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt @@ -37,6 +37,10 @@ open class BomService( return bomRepository.findByM18IdAndDeletedIsFalse(m18Id) } + open fun findByItemId(itemId: Long): Bom? { + return bomRepository.findByItemIdAndDeletedIsFalse(itemId) + } + open fun saveBom(request: SaveBomRequest): SaveBomResponse { val item = request.code.let { itemsService.findByM18BomCode(it) } ?: request.itemId?.let { itemsService.findById(it) } diff --git a/src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt b/src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt index 7d2b402..74d6522 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt @@ -3,13 +3,23 @@ package com.ffii.fpsms.modules.master.service import com.ffii.core.response.RecordsRes import com.ffii.core.support.AbstractBaseEntityService import com.ffii.core.support.JdbcDao +import com.ffii.fpsms.modules.common.SecurityUtils +import com.ffii.fpsms.modules.jobOrder.service.JobOrderBomMaterialService +import com.ffii.fpsms.modules.jobOrder.service.JobOrderProcessService +import com.ffii.fpsms.modules.jobOrder.service.JobOrderService +import com.ffii.fpsms.modules.jobOrder.web.model.CreateJobOrderBomMaterialRequest +import com.ffii.fpsms.modules.jobOrder.web.model.CreateJobOrderProcessRequest +import com.ffii.fpsms.modules.jobOrder.web.model.CreateJobOrderRequest import com.ffii.fpsms.modules.master.entity.* import com.ffii.fpsms.modules.master.entity.projections.* +import com.ffii.fpsms.modules.master.web.models.MessageResponse +import com.ffii.fpsms.modules.master.web.models.ReleaseProdScheduleLineRequest import com.ffii.fpsms.modules.master.web.models.SearchProdScheduleRequest +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import org.springframework.data.domain.PageRequest import org.springframework.stereotype.Service import java.math.BigDecimal -import java.math.RoundingMode import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.util.* @@ -25,7 +35,12 @@ open class ProductionScheduleService( private val itemService: ItemsService, private val productionScheduleRepository: ProductionScheduleRepository, private val productionScheduleLineRepository: ProductionScheduleLineRepository, - private val bomMaterialService: BomMaterialService, private val bomMaterialRepository: BomMaterialRepository, + private val bomMaterialService: BomMaterialService, + private val bomMaterialRepository: BomMaterialRepository, + private val jobOrderService: JobOrderService, + private val jobOrderBomMaterialService: JobOrderBomMaterialService, + private val bomService: BomService, + private val jobOrderProcessService: JobOrderProcessService, ) : AbstractBaseEntityService( jdbcDao, productionScheduleRepository @@ -68,12 +83,14 @@ open class ProductionScheduleService( val prodScheduleLineInfosByFg = prodScheduleLines.map { line -> val bomMaterials = line.item.id?.let { bomMaterialRepository.findAllByBomItemIdAndDeletedIsFalse(it) } ?.map { bm -> - val proportion = - if (line.prodQty > 0 && bm.bom?.outputQty != null && (bm.bom?.outputQty ?: zero) > zero) { - BigDecimal(line.prodQty).divide(bm.bom!!.outputQty, 2, RoundingMode.HALF_UP) - } else { - zero - } +// val proportion = +// if (line.prodQty > 0 && bm.bom?.outputQty != null && (bm.bom?.outputQty ?: zero) > zero) { +// BigDecimal(line.prodQty).divide(bm.bom!!.outputQty, 2, RoundingMode.HALF_UP) +// } else { +// BigDecimal.ONE +// } + + val proportion = BigDecimal(line.prodQty).divide(bm.bom?.outputQty ?: BigDecimal.ONE) val demandQty = bm.qty?.times(proportion) ?: zero @@ -150,12 +167,14 @@ open class ProductionScheduleService( val bomMaterial = line.item.id?.let { bomMaterialRepository.findAllByBomItemIdAndDeletedIsFalse(it) } bomMaterial?.map { bm -> - val proportion = - if (line.prodQty > 0 && bm.bom?.outputQty != null && (bm.bom?.outputQty ?: zero) > zero) { - BigDecimal(line.prodQty).divide(bm.bom!!.outputQty, 2, RoundingMode.HALF_UP) - } else { - zero - } +// val proportion = +// if (line.prodQty > 0 && bm.bom?.outputQty != null && (bm.bom?.outputQty ?: zero) > zero) { +// BigDecimal(line.prodQty).divide(bm.bom!!.outputQty, 2, RoundingMode.HALF_UP) +// } else { +// BigDecimal.ONE +// } + + val proportion = BigDecimal(line.prodQty).divide(bm.bom?.outputQty ?: BigDecimal.ONE) val demandQty = bm.qty?.times(proportion) ?: zero @@ -235,8 +254,76 @@ open class ProductionScheduleService( ) } - open fun detailedProdScheduleDetail(id: Long): RoughProdScheduleWithLine? { - return null + open fun detailedProdScheduleDetail(id: Long): DetailedProdScheduleWithLine { + val sqlResult = productionScheduleRepository.findDetailedProdScheduleWithLine(id) ?: throw NoSuchElementException() + + val gson = Gson() + val type = object : TypeToken?>() {}.type + val gsonResult: List? = gson.fromJson(sqlResult.prodScheduleLines, type) + + return DetailedProdScheduleWithLine( + id = sqlResult.id, + scheduleAt = sqlResult.scheduleAt, + totalEstProdCount = sqlResult.totalEstProdCount, + totalFGType = sqlResult.totalFGType, + prodScheduleLines = gsonResult + ) + } + + open fun releaseProdScheduleLine(request: ReleaseProdScheduleLineRequest): MessageResponse { + val prodScheduleLine = request.id.let { productionScheduleLineRepository.findById(it).getOrNull() } ?: throw NoSuchElementException() + val bom = prodScheduleLine.item.id?.let { bomService.findByItemId(it) } + val approver = SecurityUtils.getUser().getOrNull() + val proportion = request.demandQty.divide(bom?.outputQty ?: BigDecimal.ONE) + + // Update Prod Schedule Line Prod qty + prodScheduleLine.apply { prodQty = request.demandQty.toDouble() } + productionScheduleLineRepository.save(prodScheduleLine) + + // Create Job Order + val joRequest = CreateJobOrderRequest( + bomId = bom?.id, + reqQty = request.demandQty, + approverId = approver?.id, + prodScheduleLineId = request.id + ) + + val jo = jobOrderService.createJobOrder(joRequest) + + // Create Job Order Bom Materials + val jobmRequests = bom?.bomMaterials?.map { bm -> + CreateJobOrderBomMaterialRequest( + joId = jo.id, + itemId = bm.item?.id, + reqQty = bm.qty?.times(proportion) ?: BigDecimal.ZERO, + uomId = bm.uom?.id + ) + } + if (jobmRequests != null) { + jobOrderBomMaterialService.createJobOrderBomMaterials(jobmRequests) + } + + // Create Job Order Process + val jopRequests = bom?.bomProcesses?.map { bp -> + CreateJobOrderProcessRequest( + joId = jo.id, + processId = bp.process?.id, + seqNo = bp.seqNo, + ) + } + + if (jopRequests != null) { + jobOrderProcessService.createJobOrderProcesses(jopRequests) + } + + return MessageResponse( + id = request.id, + name = null, + code = null, + type = null, + message = "Success", + errorPosition = null + ) } //====================細排相關 START====================// diff --git a/src/main/java/com/ffii/fpsms/modules/master/web/ProductionScheduleController.kt b/src/main/java/com/ffii/fpsms/modules/master/web/ProductionScheduleController.kt index 0b1e9ad..e98dfed 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/web/ProductionScheduleController.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/web/ProductionScheduleController.kt @@ -3,11 +3,14 @@ package com.ffii.fpsms.modules.master.web import com.ffii.core.response.RecordsRes import com.ffii.core.utils.CriteriaArgsBuilder import com.ffii.fpsms.modules.master.entity.ProductionScheduleRepository +import com.ffii.fpsms.modules.master.entity.projections.DetailedProdScheduleWithLine import com.ffii.fpsms.modules.master.entity.projections.ProdScheduleInfo import com.ffii.fpsms.modules.master.entity.projections.RoughProdScheduleWithLine import com.ffii.fpsms.modules.master.service.ProductionScheduleService import com.ffii.fpsms.modules.master.service.ProductionScheduleService.FinishedGood import com.ffii.fpsms.modules.master.service.ProductionScheduleService.RoughScheduleObj +import com.ffii.fpsms.modules.master.web.models.MessageResponse +import com.ffii.fpsms.modules.master.web.models.ReleaseProdScheduleLineRequest import com.ffii.fpsms.modules.master.web.models.SearchProdScheduleRequest import jakarta.servlet.http.HttpServletRequest import org.springframework.web.bind.annotation.* @@ -41,16 +44,26 @@ class ProductionScheduleController( return productionScheduleService.getLatestScheduleAt("rough") } - @GetMapping("/detail/{id}") + @GetMapping("/detail/rough/{id}") fun getScheduleDetail(@PathVariable id: Long): RoughProdScheduleWithLine { return productionScheduleService.roughProdScheduleDetail(id) } + @GetMapping("/detail/detailed/{id}") + fun getDetailedProdScheduleDetail(@PathVariable id: Long): DetailedProdScheduleWithLine { + return productionScheduleService.detailedProdScheduleDetail(id) + } + @GetMapping("/getRecordByPage") fun allProdSchedulesByPage(@ModelAttribute request: SearchProdScheduleRequest): RecordsRes { return productionScheduleService.allProdSchedulesByPage(request); } + @PostMapping("/releaseLine") + fun releaseProdScheduleLine(request: ReleaseProdScheduleLineRequest): MessageResponse { + return productionScheduleService.releaseProdScheduleLine(request) + } + @RequestMapping(value = ["/testDetailSchedule"], method = [RequestMethod.GET]) fun generateDetailSchedule(request: HttpServletRequest?): Int { try { diff --git a/src/main/java/com/ffii/fpsms/modules/master/web/models/ReleaseProdScheduleLineRequest.kt b/src/main/java/com/ffii/fpsms/modules/master/web/models/ReleaseProdScheduleLineRequest.kt new file mode 100644 index 0000000..bb17df7 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/master/web/models/ReleaseProdScheduleLineRequest.kt @@ -0,0 +1,8 @@ +package com.ffii.fpsms.modules.master.web.models + +import java.math.BigDecimal + +data class ReleaseProdScheduleLineRequest( + val id: Long, + val demandQty: BigDecimal, +)