浏览代码

Merge remote-tracking branch 'origin/master'

reset-do-picking-order
CANCERYS\kw093 2 周前
父节点
当前提交
6ba33265ba
共有 4 个文件被更改,包括 50 次插入13 次删除
  1. +3
    -0
      src/main/java/com/ffii/fpsms/m18/entity/M18GoodsReceiptNoteLogRepository.kt
  2. +18
    -3
      src/main/java/com/ffii/fpsms/m18/model/GoodsReceiptNoteRequest.kt
  3. +1
    -1
      src/main/java/com/ffii/fpsms/m18/service/M18GoodsReceiptNoteService.kt
  4. +28
    -9
      src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt

+ 3
- 0
src/main/java/com/ffii/fpsms/m18/entity/M18GoodsReceiptNoteLogRepository.kt 查看文件

@@ -3,4 +3,7 @@ package com.ffii.fpsms.m18.entity
import com.ffii.core.support.AbstractRepository

interface M18GoodsReceiptNoteLogRepository : AbstractRepository<M18GoodsReceiptNoteLog, Long> {

/** Returns true if a successful GRN was already created for this PO (avoids core_201 duplicate). */
fun existsByPurchaseOrderIdAndStatusTrue(purchaseOrderId: Long): Boolean
}

+ 18
- 3
src/main/java/com/ffii/fpsms/m18/model/GoodsReceiptNoteRequest.kt 查看文件

@@ -1,33 +1,46 @@
package com.ffii.fpsms.m18.model

import com.fasterxml.jackson.annotation.JsonInclude

/**
* Request body for M18 Goods Receipt Note (AN) save API.
* PUT /root/api/save/an?menuCode=an
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
data class GoodsReceiptNoteRequest(
val mainan: GoodsReceiptNoteMainan,
val ant: GoodsReceiptNoteAnt,
)

@JsonInclude(JsonInclude.Include.NON_NULL)
data class GoodsReceiptNoteMainan(
val values: List<GoodsReceiptNoteMainanValue>,
)

@JsonInclude(JsonInclude.Include.NON_NULL)
data class GoodsReceiptNoteMainanValue(
val id: String? = null, // "" for create new
val beId: Int,
val code: String,
val code: String? = null, // omit; M18 auto-generates GRN code
val venId: Int,
val curId: Int,
val curId: Int, // required by M18 (core_101905)
val rate: Number,
val status: String? = "Y",
val docDate: String? = null,
val tDate: String? = null, // PO delivery date (estimatedArrivalDate)
val locId: Int? = null,
val flowTypeId: Int,
val staffId: Int,
val staffId: Int, // required by M18 (core_101905)
val cnDeptId: Int? = null,
val virDeptId: Int? = null,
)

@JsonInclude(JsonInclude.Include.NON_NULL)
data class GoodsReceiptNoteAnt(
val values: List<GoodsReceiptNoteAntValue>,
)

@JsonInclude(JsonInclude.Include.NON_NULL)
data class GoodsReceiptNoteAntValue(
val sourceType: String,
val sourceId: Long,
@@ -38,4 +51,6 @@ data class GoodsReceiptNoteAntValue(
val qty: Number,
val up: Number,
val amt: Number,
val beId: Int? = null,
val flowTypeId: Int? = null,
)

+ 1
- 1
src/main/java/com/ffii/fpsms/m18/service/M18GoodsReceiptNoteService.kt 查看文件

@@ -56,7 +56,7 @@ open class M18GoodsReceiptNoteService(
add("menuCode", MENU_CODE_AN)
param?.let { add("param", it) }
}
val queryString = queryParams.entries.joinToString("&") { (k, v) -> "$k=$v" }
val queryString = queryParams.entries.flatMap { (k, v) -> v.map { value -> "$k=$value" } }.joinToString("&")
val fullUrl = "${m18Config.BASE_URL}$M18_SAVE_GOODS_RECEIPT_NOTE_API?$queryString"
val requestJson = Gson().toJson(request)
logger.info("[M18 GRN API] call=PUT url=$fullUrl queryParams=$queryParams body=$requestJson")


+ 28
- 9
src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt 查看文件

@@ -414,37 +414,52 @@ open class StockInLineService(
* Builds M18 Goods Receipt Note (AN) request from completed PO and its completed stock-in lines.
*/
private fun buildGoodsReceiptNoteRequest(po: PurchaseOrder, stockInLines: List<StockInLine>): GoodsReceiptNoteRequest {
val poCode = po.code ?: ""
val beId = po.m18BeId?.toInt() ?: 1
val flowTypeId = when {
poCode.startsWith("TOA") -> 1
poCode.startsWith("PF") -> 2
poCode.startsWith("PP") -> 3
else -> 1
}
val mainan = GoodsReceiptNoteMainan(
values = listOf(
GoodsReceiptNoteMainanValue(
beId = po.m18BeId!!.toInt(),
code = po.code!!,
id = null, // omit; "0" and "" didn't fix core_201
beId = beId,
code = null, // omit; empty string may cause 400
venId = (po.supplier?.m18Id ?: 0L).toInt(),
curId = (po.currency?.m18Id ?: 0L).toInt(),
rate = 1,
flowTypeId = 1, // TODO temp for M18 API
staffId = 232, // TODO temp for M18 API; revert to config/default when done
virDeptId = 117, // TODO temp for M18 API
flowTypeId = flowTypeId,
staffId = 194, // Steve
virDeptId = po.shop?.m18Id?.toInt(),
tDate = (po.estimatedArrivalDate?.toLocalDate() ?: LocalDate.now()).format(DateTimeFormatter.ofPattern("MM/dd/yyyy")),
status = null, // commented out - omit
// docDate = ..., locId = ..., cnDeptId = ...
)
)
)
val sourceId = po.m18DataLog?.m18Id ?: 0L
val antValues = stockInLines.map { sil ->
val pol = sil.purchaseOrderLine!!
val unitIdFromDataLog = (pol.m18DataLog?.dataLog?.get("unitId") as? Number)?.toLong()?.toInt()
GoodsReceiptNoteAntValue(
sourceType = "po",
sourceId = sourceId,
sourceLot = sil.lotNo ?: "",
sourceLot = pol.m18Lot ?: "",
proId = (sil.item?.m18Id ?: 0L).toInt(),
locId = 39, // TODO temp for M18 API
unitId = (pol.uom?.m18Id ?: 0L).toInt(),
locId = 155,
unitId = unitIdFromDataLog ?: (pol.uom?.m18Id ?: 0L).toInt(),
qty = sil.acceptedQty?.toDouble() ?: 0.0,
up = pol.up?.toDouble() ?: 0.0,
amt = CommonUtils.getAmt(
up = pol.up ?: BigDecimal.ZERO,
discount = pol.m18Discount ?: BigDecimal.ZERO,
qty = sil.acceptedQty ?: BigDecimal.ZERO
)
),
beId = beId, // same as header
flowTypeId = flowTypeId // same as header: TOA->1, PF->2, PP->3
)
}
val ant = GoodsReceiptNoteAnt(values = antValues)
@@ -506,6 +521,10 @@ open class StockInLineService(
logger.info("[tryUpdatePurchaseOrderAndCreateGrnIfCompleted] DEBUG: Skipping M18 GRN - missing M18 ids for PO id=${savedPo.id} code=${savedPo.code}. m18BeId=${savedPo.m18BeId}, supplier.m18Id=${savedPo.supplier?.m18Id}, currency.m18Id=${savedPo.currency?.m18Id}")
return
}
if (m18GoodsReceiptNoteLogRepository.existsByPurchaseOrderIdAndStatusTrue(savedPo.id!!)) {
logger.info("[tryUpdatePurchaseOrderAndCreateGrnIfCompleted] Skipping M18 GRN - already created for PO id=${savedPo.id} code=${savedPo.code} (avoids core_201 duplicate)")
return
}
val grnRequest = buildGoodsReceiptNoteRequest(savedPo, linesForGrn)
val grnRequestJson = Gson().toJson(grnRequest)
logger.info("[tryUpdatePurchaseOrderAndCreateGrnIfCompleted] M18 GRN API request (for discussion with M18) PO id=${savedPo.id} code=${savedPo.code}: $grnRequestJson")


正在加载...
取消
保存