|
|
|
@@ -86,6 +86,9 @@ import org.springframework.data.domain.Page |
|
|
|
import org.springframework.data.domain.Pageable |
|
|
|
import com.ffii.fpsms.modules.deliveryOrder.entity.models.DeliveryOrderInfoLite |
|
|
|
import com.ffii.fpsms.modules.deliveryOrder.entity.models.DeliveryOrderInfoLiteDto |
|
|
|
import com.ffii.fpsms.modules.deliveryOrder.entity.models.DeliveryOrderLineInfo |
|
|
|
import com.ffii.fpsms.modules.master.entity.Items |
|
|
|
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLine |
|
|
|
import com.ffii.fpsms.modules.stock.entity.InventoryLotLine |
|
|
|
import com.ffii.fpsms.modules.stock.entity.projection.StockOutLineInfo |
|
|
|
import java.util.Locale |
|
|
|
@@ -1242,18 +1245,18 @@ open class DeliveryOrderService( |
|
|
|
val truckNo = doPickOrderRecord.truckLanceCode ?: "" |
|
|
|
val selectedPickOrder = pickOrderRepository.findById(pickOrderId).orElse(null) |
|
|
|
|
|
|
|
val allLines = deliveryNoteInfo.flatMap { info -> |
|
|
|
info.deliveryOrderLines.map { line -> line } |
|
|
|
} |
|
|
|
|
|
|
|
val pickOrderIdByDoId = doPickOrderLineRecords.mapNotNull { rec -> |
|
|
|
val doId = rec.doOrderId |
|
|
|
val poId = rec.pickOrderId |
|
|
|
if (doId != null && poId != null) doId to poId else null |
|
|
|
}.toMap() |
|
|
|
|
|
|
|
val exportLines = deliveryNoteExportLines(deliveryNoteInfo) |
|
|
|
|
|
|
|
val pickOrderLines = pickOrderIds.flatMap { pid -> |
|
|
|
pickOrderLineRepository.findAllByPickOrderId(pid) |
|
|
|
} |
|
|
|
|
|
|
|
val pickOrderLineIdsByItemId = pickOrderLines |
|
|
|
.groupBy { it.item?.id } |
|
|
|
.mapValues { (_, lines) -> lines.mapNotNull { it.id } } |
|
|
|
|
|
|
|
|
|
|
|
val allPickOrderLineIds = pickOrderLines.mapNotNull { it.id } |
|
|
|
val stockOutLinesByPickOrderLineId: Map<Long, List<StockOutLineInfo>> = |
|
|
|
if (allPickOrderLineIds.isNotEmpty()) { |
|
|
|
@@ -1269,7 +1272,7 @@ open class DeliveryOrderService( |
|
|
|
?.replace(" ", "") |
|
|
|
?: "" |
|
|
|
|
|
|
|
val uniqueItemIdsForSort = allLines.mapNotNull { it.itemId }.distinct() |
|
|
|
val uniqueItemIdsForSort = exportLines.mapNotNull { it.line.itemId }.distinct() |
|
|
|
val itemsById = if (uniqueItemIdsForSort.isNotEmpty()) { |
|
|
|
itemsRepository.findAllById(uniqueItemIdsForSort).associateBy { it.id!! } |
|
|
|
} else { |
|
|
|
@@ -1277,17 +1280,17 @@ open class DeliveryOrderService( |
|
|
|
} |
|
|
|
|
|
|
|
val sortedLines = when (doStoreFloorKey) { |
|
|
|
"2F" -> allLines.sortedWith( |
|
|
|
"2F" -> exportLines.sortedWith( |
|
|
|
compareBy( |
|
|
|
{ line -> itemsById[line.itemId]?.item_Order ?: Int.MAX_VALUE }, |
|
|
|
{ line -> line.itemNo }, |
|
|
|
{ row -> itemsById[row.line.itemId]?.item_Order ?: Int.MAX_VALUE }, |
|
|
|
{ row -> row.line.itemNo }, |
|
|
|
), |
|
|
|
) |
|
|
|
"4F" -> allLines.sortedBy { line -> |
|
|
|
line.itemId?.let { getWarehouseOrderByItemId(it) } ?: Int.MAX_VALUE |
|
|
|
"4F" -> exportLines.sortedBy { row -> |
|
|
|
row.line.itemId?.let { getWarehouseOrderByItemId(it) } ?: Int.MAX_VALUE |
|
|
|
} |
|
|
|
else -> allLines.sortedBy { line -> |
|
|
|
line.itemId?.let { getWarehouseOrderByItemId(it) } ?: Int.MAX_VALUE |
|
|
|
else -> exportLines.sortedBy { row -> |
|
|
|
row.line.itemId?.let { getWarehouseOrderByItemId(it) } ?: Int.MAX_VALUE |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@@ -1300,61 +1303,19 @@ open class DeliveryOrderService( |
|
|
|
emptyMap() |
|
|
|
} |
|
|
|
|
|
|
|
val itemsMap = itemsById |
|
|
|
|
|
|
|
sortedLines.forEach { line -> |
|
|
|
val field = mutableMapOf<String, Any>() |
|
|
|
|
|
|
|
field["sequenceNumber"] = (fields.size + 1).toString() |
|
|
|
field["itemNo"] = line.itemNo |
|
|
|
field["itemName"] = line.itemName ?: "" |
|
|
|
field["uom"] = line.uom ?: "" |
|
|
|
|
|
|
|
val actualPickQty = if (line.itemId != null) { |
|
|
|
val pickOrderLineIdsForItem = pickOrderLineIdsByItemId[line.itemId] ?: emptyList() |
|
|
|
val totalQty = pickOrderLineIdsForItem.sumOf { polId -> |
|
|
|
stockOutLinesByPickOrderLineId[polId].orEmpty().sumOf { it.qty } |
|
|
|
} |
|
|
|
totalQty.toString() |
|
|
|
} else { |
|
|
|
line.qty.toString() |
|
|
|
} |
|
|
|
field["qty"] = actualPickQty |
|
|
|
|
|
|
|
field["shortName"] = line.uomShortDesc ?: "" |
|
|
|
|
|
|
|
val route = line.itemId?.let { itemId -> |
|
|
|
routeFromStockOutsForItem( |
|
|
|
itemId, |
|
|
|
pickOrderLineIdsByItemId, |
|
|
|
stockOutLinesByPickOrderLineId, |
|
|
|
illById, |
|
|
|
).takeIf { it != "-" } ?: getWarehouseCodeByItemId(itemId) |
|
|
|
} ?: "-" |
|
|
|
field["route"] = route |
|
|
|
|
|
|
|
val lotNo = line.itemId?.let { itemId -> |
|
|
|
val pickOrderLineIdsForItem = pickOrderLineIdsByItemId[itemId] ?: emptyList() |
|
|
|
val lotNumbers = pickOrderLineIdsForItem.flatMap { polId -> |
|
|
|
stockOutLinesByPickOrderLineId[polId].orEmpty().mapNotNull { it.lotNo } |
|
|
|
}.distinct().joinToString(", ") |
|
|
|
|
|
|
|
lotNumbers.ifBlank { "沒有庫存" } |
|
|
|
} ?: "沒有庫存" |
|
|
|
|
|
|
|
field["lotNo"] = lotNo |
|
|
|
|
|
|
|
val signOff = line.itemId?.let { itemId -> |
|
|
|
val item = itemsMap[itemId] |
|
|
|
if (item?.isEgg == true) { |
|
|
|
"簽署: __________" |
|
|
|
} else { |
|
|
|
"" |
|
|
|
} |
|
|
|
} ?: "" |
|
|
|
field["signOff"] = signOff |
|
|
|
|
|
|
|
fields.add(field) |
|
|
|
sortedLines.forEach { row -> |
|
|
|
fields.add( |
|
|
|
buildDeliveryNotePdfLineField( |
|
|
|
deliveryOrderId = row.deliveryOrderId, |
|
|
|
line = row.line, |
|
|
|
sequenceNumber = fields.size + 1, |
|
|
|
pickOrderIdByDoId = pickOrderIdByDoId, |
|
|
|
pickOrderLines = pickOrderLines, |
|
|
|
stockOutLinesByPickOrderLineId = stockOutLinesByPickOrderLineId, |
|
|
|
illById = illById, |
|
|
|
itemsById = itemsById, |
|
|
|
), |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
params["dnTitle"] = "送貨單" |
|
|
|
@@ -1386,15 +1347,110 @@ open class DeliveryOrderService( |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
fun routeFromStockOutsForItem( |
|
|
|
itemId: Long, |
|
|
|
pickOrderLineIdsByItemId: Map<Long?, List<Long>>, |
|
|
|
data class DeliveryNoteExportLine( |
|
|
|
val deliveryOrderId: Long, |
|
|
|
val line: DeliveryOrderLineInfo, |
|
|
|
) |
|
|
|
|
|
|
|
fun deliveryNoteExportLines(deliveryNoteInfo: List<DeliveryOrderInfo>): List<DeliveryNoteExportLine> = |
|
|
|
deliveryNoteInfo.flatMap { info -> |
|
|
|
info.deliveryOrderLines.map { line -> DeliveryNoteExportLine(info.id, line) } |
|
|
|
} |
|
|
|
|
|
|
|
fun resolvePickOrderLineIdForDeliveryNoteLine( |
|
|
|
deliveryOrderId: Long, |
|
|
|
itemId: Long?, |
|
|
|
pickOrderIdByDoId: Map<Long, Long>, |
|
|
|
pickOrderLines: List<PickOrderLine>, |
|
|
|
): Long? { |
|
|
|
if (itemId == null) return null |
|
|
|
val pickOrderId = pickOrderIdByDoId[deliveryOrderId] ?: return null |
|
|
|
return pickOrderLines |
|
|
|
.firstOrNull { pol -> pol.pickOrder?.id == pickOrderId && pol.item?.id == itemId } |
|
|
|
?.id |
|
|
|
} |
|
|
|
|
|
|
|
fun buildDeliveryNotePdfLineField( |
|
|
|
deliveryOrderId: Long, |
|
|
|
line: DeliveryOrderLineInfo, |
|
|
|
sequenceNumber: Int, |
|
|
|
pickOrderIdByDoId: Map<Long, Long>, |
|
|
|
pickOrderLines: List<PickOrderLine>, |
|
|
|
stockOutLinesByPickOrderLineId: Map<Long, List<StockOutLineInfo>>, |
|
|
|
illById: Map<Long, InventoryLotLine>, |
|
|
|
itemsById: Map<Long, Items>, |
|
|
|
): MutableMap<String, Any> { |
|
|
|
val field = mutableMapOf<String, Any>() |
|
|
|
field["sequenceNumber"] = sequenceNumber.toString() |
|
|
|
field["itemNo"] = line.itemNo |
|
|
|
field["itemName"] = line.itemName ?: "" |
|
|
|
field["uom"] = line.uom ?: "" |
|
|
|
field["shortName"] = line.uomShortDesc ?: "" |
|
|
|
|
|
|
|
val polId = resolvePickOrderLineIdForDeliveryNoteLine( |
|
|
|
deliveryOrderId = deliveryOrderId, |
|
|
|
itemId = line.itemId, |
|
|
|
pickOrderIdByDoId = pickOrderIdByDoId, |
|
|
|
pickOrderLines = pickOrderLines, |
|
|
|
) |
|
|
|
val polIdsForRow = listOfNotNull(polId) |
|
|
|
|
|
|
|
field["qty"] = if (polId != null) { |
|
|
|
sumActualPickQtyForPickOrderLineIds(polIdsForRow, stockOutLinesByPickOrderLineId) |
|
|
|
} else { |
|
|
|
line.qty.toString() |
|
|
|
} |
|
|
|
|
|
|
|
val itemId = line.itemId |
|
|
|
field["route"] = when { |
|
|
|
itemId != null && polId != null -> { |
|
|
|
routeFromStockOutsForPickOrderLineIds(polIdsForRow, stockOutLinesByPickOrderLineId, illById) |
|
|
|
.takeIf { it != "-" } ?: getWarehouseCodeByItemId(itemId) ?: "-" |
|
|
|
} |
|
|
|
itemId != null -> getWarehouseCodeByItemId(itemId) ?: "-" |
|
|
|
else -> "-" |
|
|
|
} |
|
|
|
|
|
|
|
field["lotNo"] = if (itemId != null && polId != null) { |
|
|
|
lotNumbersForPickOrderLineIds(polIdsForRow, stockOutLinesByPickOrderLineId).ifBlank { "沒有庫存" } |
|
|
|
} else { |
|
|
|
"沒有庫存" |
|
|
|
} |
|
|
|
|
|
|
|
field["signOff"] = if (itemId != null && itemsById[itemId]?.isEgg == true) { |
|
|
|
"簽署: __________" |
|
|
|
} else { |
|
|
|
"" |
|
|
|
} |
|
|
|
|
|
|
|
return field |
|
|
|
} |
|
|
|
|
|
|
|
fun sumActualPickQtyForPickOrderLineIds( |
|
|
|
pickOrderLineIds: List<Long>, |
|
|
|
stockOutLinesByPickOrderLineId: Map<Long, List<StockOutLineInfo>>, |
|
|
|
): String { |
|
|
|
if (pickOrderLineIds.isEmpty()) return "0" |
|
|
|
return pickOrderLineIds.sumOf { polId -> |
|
|
|
stockOutLinesByPickOrderLineId[polId].orEmpty().sumOf { it.qty } |
|
|
|
}.toString() |
|
|
|
} |
|
|
|
|
|
|
|
fun lotNumbersForPickOrderLineIds( |
|
|
|
pickOrderLineIds: List<Long>, |
|
|
|
stockOutLinesByPickOrderLineId: Map<Long, List<StockOutLineInfo>>, |
|
|
|
): String = |
|
|
|
pickOrderLineIds.flatMap { polId -> |
|
|
|
stockOutLinesByPickOrderLineId[polId].orEmpty().mapNotNull { it.lotNo } |
|
|
|
}.distinct().joinToString(", ") |
|
|
|
|
|
|
|
fun routeFromStockOutsForPickOrderLineIds( |
|
|
|
pickOrderLineIds: List<Long>, |
|
|
|
stockOutLinesByPickOrderLineId: Map<Long, List<StockOutLineInfo>>, |
|
|
|
illById: Map<Long, InventoryLotLine>, |
|
|
|
): String { |
|
|
|
val polIds = pickOrderLineIdsByItemId[itemId] ?: return "-" |
|
|
|
val codes = linkedSetOf<String>() |
|
|
|
for (polId in polIds) { |
|
|
|
for (polId in pickOrderLineIds) { |
|
|
|
for (sol in stockOutLinesByPickOrderLineId[polId].orEmpty()) { |
|
|
|
val illId = sol.inventoryLotLineId ?: continue |
|
|
|
val ill = illById[illId] ?: continue |
|
|
|
@@ -1403,6 +1459,16 @@ open class DeliveryOrderService( |
|
|
|
} |
|
|
|
return if (codes.isEmpty()) "-" else codes.joinToString(", ") |
|
|
|
} |
|
|
|
|
|
|
|
fun routeFromStockOutsForItem( |
|
|
|
itemId: Long, |
|
|
|
pickOrderLineIdsByItemId: Map<Long?, List<Long>>, |
|
|
|
stockOutLinesByPickOrderLineId: Map<Long, List<StockOutLineInfo>>, |
|
|
|
illById: Map<Long, InventoryLotLine>, |
|
|
|
): String { |
|
|
|
val polIds = pickOrderLineIdsByItemId[itemId] ?: return "-" |
|
|
|
return routeFromStockOutsForPickOrderLineIds(polIds, stockOutLinesByPickOrderLineId, illById) |
|
|
|
} |
|
|
|
//Print Delivery Note |
|
|
|
@Transactional |
|
|
|
open fun printDeliveryNote(request: PrintDeliveryNoteRequest) { |
|
|
|
|