Explorar el Código

job order bom status

and do merge
production
CANCERYS\kw093 hace 1 semana
padre
commit
b02f176e08
Se han modificado 18 ficheros con 961 adiciones y 93 borrados
  1. +4
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DeliveryOrderPickOrder.kt
  2. +802
    -85
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchReleaseService.kt
  3. +4
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/WorkbenchReleaseTypeSupport.kt
  4. +28
    -4
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DoWorkbenchController.kt
  5. +11
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/WorkbenchBatchReleaseRequest.kt
  6. +35
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/WorkbenchMergeTicketModels.kt
  7. +6
    -0
      src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt
  8. +4
    -1
      src/main/java/com/ffii/fpsms/modules/master/entity/BomRepository.kt
  9. +2
    -0
      src/main/java/com/ffii/fpsms/modules/master/entity/projections/BomCombo.kt
  10. +12
    -0
      src/main/java/com/ffii/fpsms/modules/master/enums/BomStatus.kt
  11. +12
    -0
      src/main/java/com/ffii/fpsms/modules/master/enums/BomStatusConverter.kt
  12. +15
    -0
      src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt
  13. +1
    -1
      src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt
  14. +9
    -2
      src/main/java/com/ffii/fpsms/modules/master/web/BomController.kt
  15. +1
    -0
      src/main/java/com/ffii/fpsms/modules/master/web/models/EditBomRequest.kt
  16. +1
    -0
      src/main/java/com/ffii/fpsms/modules/master/web/models/ItemUomRequest.kt
  17. +7
    -0
      src/main/resources/db/changelog/changes/20260609_Enson/02_setting.sql
  18. +7
    -0
      src/main/resources/db/changelog/changes/20260609_Enson/03_bom_status.sql

+ 4
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DeliveryOrderPickOrder.kt Ver fichero

@@ -61,6 +61,10 @@ class DeliveryOrderPickOrder {
@Column(name = "cartonQty")
var cartonQty: Int? = null

/** Merge lineage: equals own [id] until soft-deleted into a successor [TI-M] header. */
@Column(name = "relationshipId")
var relationshipId: Long? = null

@CreationTimestamp
@Column(name = "created")
var created: LocalDateTime? = null


+ 802
- 85
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchReleaseService.kt
La diferencia del archivo ha sido suprimido porque es demasiado grande
Ver fichero


+ 4
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/WorkbenchReleaseTypeSupport.kt Ver fichero

@@ -49,6 +49,10 @@ object WorkbenchReleaseTypeSupport {
else -> BATCH
}

/** [TI-M] merged workbench ticket release type (batch-family merge). */
fun mergeTicketReleaseType(isSingleRelease: Boolean): String =
if (isSingleRelease) IS_EXTRA_SINGLE else IS_EXTRA_BATCH

fun upgradedReleaseTypeIfNeeded(currentType: String?, isExtraRelease: Boolean, isSingleRelease: Boolean): String? {
if (!isExtraRelease) return null
val cur = currentType?.trim()?.lowercase().orEmpty()


+ 28
- 4
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DoWorkbenchController.kt Ver fichero

@@ -178,10 +178,14 @@ class DoWorkbenchController(
*/
@PostMapping("/batch-release/async-v2")
fun startWorkbenchBatchReleaseAsyncV2(
@RequestBody ids: List<Long>,
@RequestBody request: WorkbenchBatchReleaseRequest,
@RequestParam(defaultValue = "1") userId: Long
): MessageResponse {
return doWorkbenchReleaseService.startBatchReleaseAsyncV2(ids, userId)
return doWorkbenchReleaseService.startBatchReleaseAsyncV2(
request.ids,
userId,
request.mergeExtraIntoLaneTicket,
)
}

/**
@@ -200,10 +204,14 @@ class DoWorkbenchController(
/** Synchronous batch release V2 (same semantics as async-v2; for tools / tests). */
@PostMapping("/batch-release/sync-v2")
fun workbenchBatchReleaseSyncV2(
@RequestBody ids: List<Long>,
@RequestBody request: WorkbenchBatchReleaseRequest,
@RequestParam(defaultValue = "1") userId: Long
): MessageResponse {
return doWorkbenchReleaseService.releaseBatchV2(ids, userId)
return doWorkbenchReleaseService.releaseBatchV2(
request.ids,
userId,
request.mergeExtraIntoLaneTicket,
)
}
@GetMapping("/batch-release/progress/{jobId}")
@@ -211,6 +219,22 @@ class DoWorkbenchController(
return doWorkbenchReleaseService.getBatchReleaseProgress(jobId)
}

/** Case 3: unassigned plain batch/single + isExtra tickets on the same lane (for merge UI). */
@GetMapping("/merge-ticket-candidates")
fun getWorkbenchMergeTicketCandidates(
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) requiredDate: LocalDate,
@RequestParam(required = false) shopSearch: String?,
): WorkbenchMergeTicketCandidatesResponse =
doWorkbenchReleaseService.getMergeTicketCandidates(requiredDate, shopSearch)

/** Case 3: merge selected batch/single + isExtra into a new [TI-M] ticket. */
@PostMapping("/merge-tickets")
fun mergeWorkbenchTickets(@RequestBody request: WorkbenchMergeTicketsRequest): MessageResponse =
doWorkbenchReleaseService.mergeTicketsCase3(
request.batchOrSingleDopoId,
request.isExtraDopoId,
)

@GetMapping("/ticket-release-table/{startDate}&{endDate}")
fun getWorkbenchTicketReleaseTable(
@PathVariable startDate: LocalDate,


+ 11
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/WorkbenchBatchReleaseRequest.kt Ver fichero

@@ -0,0 +1,11 @@
package com.ffii.fpsms.modules.deliveryOrder.web.models

/**
* Workbench batch release body (async-v2 / sync-v2).
* [mergeExtraIntoLaneTicket]: when true, isExtra DOs join batch/single family (isExtrabatch / isExtrasingle);
* when false, standalone `releaseType=isExtra` tickets with `TI-E-` prefix.
*/
data class WorkbenchBatchReleaseRequest(
val ids: List<Long> = emptyList(),
val mergeExtraIntoLaneTicket: Boolean = true,
)

+ 35
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/WorkbenchMergeTicketModels.kt Ver fichero

@@ -0,0 +1,35 @@
package com.ffii.fpsms.modules.deliveryOrder.web.models

import com.fasterxml.jackson.annotation.JsonFormat
import java.time.LocalDate
import java.time.LocalTime

data class WorkbenchMergeTicketCandidate(
val id: Long,
val ticketNo: String?,
val releaseType: String?,
val shopId: Long?,
val shopCode: String?,
val shopName: String?,
val storeId: String?,
val truckId: Long?,
@JsonFormat(pattern = "yyyy-MM-dd")
val requiredDeliveryDate: LocalDate?,
val truckLanceCode: String?,
@JsonFormat(pattern = "HH:mm")
val truckDepartureTime: LocalTime?,
val loadingSequence: Int?,
val deliveryOrderCodes: List<String>,
/** Stable lane identity for same-truck merge matching (2/F, 4/F, truck-X). */
val laneKey: String,
)

data class WorkbenchMergeTicketCandidatesResponse(
val batchFamilyTickets: List<WorkbenchMergeTicketCandidate>,
val isExtraTickets: List<WorkbenchMergeTicketCandidate>,
)

data class WorkbenchMergeTicketsRequest(
val batchOrSingleDopoId: Long,
val isExtraDopoId: Long,
)

+ 6
- 0
src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt Ver fichero

@@ -3,6 +3,8 @@ 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 com.ffii.fpsms.modules.master.enums.BomStatus
import com.ffii.fpsms.modules.master.enums.BomStatusConverter
import jakarta.persistence.*
import jakarta.validation.constraints.NotNull
import jakarta.validation.constraints.Size
@@ -87,4 +89,8 @@ open class Bom : BaseEntity<Long>() {

@Column(name = "baseScore", precision = 14, scale = 2)
open var baseScore: BigDecimal? = null

@Column(name = "status", nullable = false, length = 20)
@Convert(converter = BomStatusConverter::class)
open var status: BomStatus = BomStatus.ACTIVE
}

+ 4
- 1
src/main/java/com/ffii/fpsms/modules/master/entity/BomRepository.kt Ver fichero

@@ -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.BomCombo
import com.ffii.fpsms.modules.master.enums.BomStatus
import org.springframework.stereotype.Repository
import java.io.Serializable
import org.springframework.data.jpa.repository.Query
@@ -27,8 +28,10 @@ interface BomRepository : AbstractRepository<Bom, Long> {
fun findByItemIdAndDeletedIsFalse(itemId: Serializable): Bom?

fun findBomComboByDeletedIsFalse(): List<BomCombo>
fun findAllByItemIdAndDeletedIsFalse(itemId: Long): List<Bom>

fun findBomComboByDeletedIsFalseAndStatus(status: BomStatus): List<BomCombo>
fun findAllByItemIdAndDeletedIsFalse(itemId: Long): List<Bom>
fun findAllByItemIdAndStatusAndDeletedIsFalse(itemId: Long, status: BomStatus): List<Bom>
@Query("SELECT b.id FROM Bom b WHERE b.deleted = false ORDER BY b.id")
fun findAllIdsByDeletedIsFalse(): List<Long>



+ 2
- 0
src/main/java/com/ffii/fpsms/modules/master/entity/projections/BomCombo.kt Ver fichero

@@ -13,4 +13,6 @@ interface BomCombo {
val outputQtyUom: String?;
@get:Value("#{target.description}")
val description: String?;
@get:Value("#{target.status?.value}")
val status: String?;
}

+ 12
- 0
src/main/java/com/ffii/fpsms/modules/master/enums/BomStatus.kt Ver fichero

@@ -0,0 +1,12 @@
package com.ffii.fpsms.modules.master.enums

enum class BomStatus(val value: String) {
ACTIVE("active"),
INACTIVE("inactive");

companion object {
fun fromValue(value: String): BomStatus =
entries.find { it.value == value }
?: throw IllegalArgumentException("Unknown BOM status: $value")
}
}

+ 12
- 0
src/main/java/com/ffii/fpsms/modules/master/enums/BomStatusConverter.kt Ver fichero

@@ -0,0 +1,12 @@
package com.ffii.fpsms.modules.master.enums

import jakarta.persistence.AttributeConverter
import jakarta.persistence.Converter

@Converter(autoApply = true)
class BomStatusConverter : AttributeConverter<BomStatus, String> {
override fun convertToDatabaseColumn(attribute: BomStatus?): String? = attribute?.value

override fun convertToEntityAttribute(dbData: String?): BomStatus? =
dbData?.let { BomStatus.fromValue(it) }
}

+ 15
- 0
src/main/java/com/ffii/fpsms/modules/master/service/BomService.kt Ver fichero

@@ -43,6 +43,8 @@ import com.ffii.fpsms.m18.entity.M18BomShopSyncLogRepository
import com.ffii.fpsms.modules.common.SettingNames
import com.ffii.fpsms.modules.settings.entity.Settings
import com.ffii.fpsms.modules.settings.service.SettingsService
import com.ffii.fpsms.modules.master.enums.BomStatus
import com.ffii.core.exception.BadRequestException

@Service
open class BomService(
@@ -141,6 +143,11 @@ open class BomService(
.minByOrNull { if (it.description == "FG") 0 else 1 }
?: bomRepository.findAllByItemIdAndDeletedIsFalse(itemId).firstOrNull()
}
open fun findByItemIdAndStatus(itemId: Long, status: BomStatus): Bom? {
return bomRepository.findAllByItemIdAndStatusAndDeletedIsFalse(itemId, status)
.minByOrNull { if (it.description == "FG") 0 else 1 }
?: bomRepository.findAllByItemIdAndStatusAndDeletedIsFalse(itemId, status).firstOrNull()
}

/** Resolve BOM header for a finished-good item code ([Items.code] on [Bom.item]). */
open fun findBomSummaryByItemCode(itemCodeTrimmed: String): BomIdByItemCodeResponse {
@@ -240,6 +247,13 @@ open class BomService(
else -> "Other"
}
}
request.status?.let { raw ->
bom.status = try {
BomStatus.fromValue(raw.trim().lowercase())
} catch (_: IllegalArgumentException) {
throw BadRequestException("Invalid BOM status: $raw")
}
}

val replaceMaterials = request.materials != null
val replaceProcesses = request.processes != null
@@ -2962,6 +2976,7 @@ println("=====================================")
description = bom.description,
outputQty = bom.outputQty,
outputQtyUom = bom.outputQtyUom,
status = bom.status.value,
materials = materials,
processes = processes
)


+ 1
- 1
src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt Ver fichero

@@ -726,7 +726,7 @@ open class ProductionScheduleService(
LEFT JOIN items ON bom.itemId = items.id
LEFT JOIN inventory ON items.id = inventory.itemId
left join item_fake_onhand on items.code = item_fake_onhand.itemCode
WHERE bom.deleted = 0 and bom.description = 'FG'
WHERE bom.deleted = 0 and bom.description = 'FG' and bom.status = 'active'
-- and bom.itemId != 16771
) AS i
WHERE 1


+ 9
- 2
src/main/java/com/ffii/fpsms/modules/master/web/BomController.kt Ver fichero

@@ -2,6 +2,7 @@ package com.ffii.fpsms.modules.master.web

import com.ffii.fpsms.modules.master.entity.Bom
import com.ffii.fpsms.modules.master.entity.BomRepository
import com.ffii.fpsms.modules.master.enums.BomStatus
import com.ffii.fpsms.modules.master.entity.projections.BomCombo
import com.ffii.fpsms.modules.master.service.BomService
import org.springframework.core.io.ByteArrayResource
@@ -108,8 +109,14 @@ fun downloadBomFormatIssueLog(
}

@GetMapping("/combo")
fun getCombo(): List<BomCombo> {
return bomRepository.findBomComboByDeletedIsFalse();
fun getCombo(
@RequestParam(defaultValue = "false") includeInactive: Boolean,
): List<BomCombo> {
return if (includeInactive) {
bomRepository.findBomComboByDeletedIsFalse()
} else {
bomRepository.findBomComboByDeletedIsFalseAndStatus(BomStatus.ACTIVE)
}
}

@GetMapping("/combo/issues")


+ 1
- 0
src/main/java/com/ffii/fpsms/modules/master/web/models/EditBomRequest.kt Ver fichero

@@ -30,6 +30,7 @@ data class EditBomRequest(
val complexity: Int? = null,
val isDrink: Boolean? = null,
val isPowderMixture: Boolean? = null,
val status: String? = null,

// children
val materials: List<EditBomMaterialRequest>? = null,


+ 1
- 0
src/main/java/com/ffii/fpsms/modules/master/web/models/ItemUomRequest.kt Ver fichero

@@ -122,6 +122,7 @@ data class BomDetailResponse(
val description: String?,
val outputQty: BigDecimal?,
val outputQtyUom: String?,
val status: String?,
val materials: List<BomMaterialDto>,
val processes: List<BomProcessDto>
)

+ 7
- 0
src/main/resources/db/changelog/changes/20260609_Enson/02_setting.sql Ver fichero

@@ -0,0 +1,7 @@
--liquibase formatted sql

-- Add column relationshipId to delivery_order_pick_order
--changeset Enson:20260609-01
ALTER TABLE delivery_order_pick_order
ADD COLUMN relationshipId INT NULL;
UPDATE delivery_order_pick_order SET relationshipId = id WHERE relationshipId IS NULL OR relationshipId = 0;

+ 7
- 0
src/main/resources/db/changelog/changes/20260609_Enson/03_bom_status.sql Ver fichero

@@ -0,0 +1,7 @@
--liquibase formatted sql

--changeset Enson:20260609-bom-status
ALTER TABLE bom
ADD COLUMN status VARCHAR(20) NOT NULL DEFAULT 'active' AFTER type;

UPDATE bom SET status = 'active' WHERE status IS NULL OR status = '';

Cargando…
Cancelar
Guardar