Browse Source

updated import stock take function, supporting function to print all QR codes by searching DO ID

master
kelvin.yau 1 week ago
parent
commit
373f3d844d
5 changed files with 67 additions and 5 deletions
  1. +8
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DeliveryOrderController.kt
  2. +19
    -4
      src/main/java/com/ffii/fpsms/modules/master/service/ItemsService.kt
  3. +4
    -0
      src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLineRepository.kt
  4. +29
    -1
      src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt
  5. +7
    -0
      src/main/java/com/ffii/fpsms/modules/stock/web/model/PrintQrCodeForDoRequest.kt

+ 8
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DeliveryOrderController.kt View File

@@ -33,11 +33,14 @@ import java.io.OutputStream
import java.io.UnsupportedEncodingException
import java.text.ParseException
import java.time.LocalDateTime
import com.ffii.fpsms.modules.deliveryOrder.web.models.PrintQrCodeForDoRequest
import com.ffii.fpsms.modules.stock.service.StockInLineService

@RequestMapping("/do")
@RestController
class DeliveryOrderController(
private val deliveryOrderService: DeliveryOrderService,
private val stockInLineService: StockInLineService,
) {
@GetMapping("/list")
fun getDoList(): List<DeliveryOrderInfo> {
@@ -217,4 +220,9 @@ class DeliveryOrderController(
fun printDN(@ModelAttribute request: PrintDNLabelsRequest) {
deliveryOrderService.printDNLabels(request)
}

@GetMapping("/batchPrintQrCode")
fun printQrCodeForDeliveryOrder(@ModelAttribute request: PrintQrCodeForDoRequest) {
stockInLineService.printQrCodeForDeliveryOrder(request)
}
}

+ 19
- 4
src/main/java/com/ffii/fpsms/modules/master/service/ItemsService.kt View File

@@ -25,6 +25,7 @@ import java.io.FileInputStream
import java.math.BigDecimal
import com.ffii.fpsms.modules.stock.entity.Inventory
import com.ffii.fpsms.modules.stock.entity.InventoryLotLineRepository
import com.ffii.fpsms.modules.stock.entity.InventoryLotRepository
import com.ffii.fpsms.modules.stock.entity.InventoryRepository
import com.ffii.fpsms.modules.stock.entity.StockIn
import com.ffii.fpsms.modules.stock.entity.StockInLineRepository
@@ -61,6 +62,7 @@ open class ItemsService(
private val stockInLineService: StockInLineService,
private val stockInLineRepository: StockInLineRepository,
private val inventoryLotLineRepository: InventoryLotLineRepository,
private val inventoryLotRepository: InventoryLotRepository,
): AbstractBaseEntityService<Items, Long, ItemsRepository>(jdbcDao, itemsRepository) {

private val excelImportPath: String = System.getProperty("user.home") + "/Downloads/StockTakeImport/"
@@ -908,9 +910,12 @@ open class ItemsService(
// Calculate expiry date (+30 days)
val expiryDate = LocalDateTime.now().plusDays(30).toLocalDate()

// Generate lotNo: LT-YYYYMMDD-itemCode
// Generate productLotNo: LT-YYYYMMDD-itemCode (for productLotNo field)
val dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))
val lotNo = "LT-$dateStr-$itemCode"
val productLotNo = "LT-$dateStr-$itemCode"

// Generate lotNo: LT-YYYYMMDD-XXXX (sequential number, same for StockInLine and InventoryLot)
val lotNo = stockInLineService.assignLotNo()

// Generate dnNo: DN-YYYYMMDD-itemCode
val dnNo = "DN-$dateStr-$itemCode"
@@ -924,7 +929,8 @@ open class ItemsService(
expiryDate = expiryDate,
warehouseId = warehouse?.id,
stockTakeLineId = savedStockTakeLine.id,
dnNo = dnNo, // Set dnNo
dnNo = dnNo,
productLotNo = productLotNo, // LT-YYYYMMDD-itemCode
qcAccept = true,
status = StockInLineStatus.PENDING.status
)
@@ -970,6 +976,7 @@ open class ItemsService(
id = savedStockInLine.id
status = StockInLineStatus.PENDING.status
this.dnNo = dnNo
this.productLotNo = lotNo
this.qcAccept = true
this.acceptedQty = qty
this.acceptQty = qty
@@ -1002,7 +1009,14 @@ open class ItemsService(
logger.warn("Row ${i + 1}: InventoryLot was not created for StockInLine ${updatedForLot.id}")
logWriter.writeRowError(i, "InventoryLot was not created")
} else {
logger.info("Row ${i + 1}: InventoryLot created (ID: ${refreshedStockInLine.inventoryLot?.id}, lotNo: ${refreshedStockInLine.inventoryLot?.lotNo})")
// Update InventoryLot's lotNo to match StockInLine's lotNo (LT-YYYYMMDD-XXXX format)
val inventoryLot = refreshedStockInLine.inventoryLot!!
if (inventoryLot.lotNo != lotNo) {
inventoryLot.lotNo = lotNo
inventoryLotRepository.saveAndFlush(inventoryLot)
logger.info("Row ${i + 1}: Updated InventoryLot lotNo to '$lotNo' to match StockInLine (InventoryLot ID: ${inventoryLot.id})")
}
logger.info("Row ${i + 1}: InventoryLot created (ID: ${inventoryLot.id}, lotNo: ${inventoryLot.lotNo})")
}

// Step 7b: Second update to RECEIVED with inventoryLotLines to create InventoryLotLine
@@ -1017,6 +1031,7 @@ open class ItemsService(
id = savedStockInLine.id
status = StockInLineStatus.RECEIVED.status // Explicitly set to RECEIVED
this.dnNo = dnNo
this.productLotNo = productLotNo
this.acceptedQty = qty
this.acceptQty = qty
this.inventoryLotLines = inventoryLotLines // REQUIRED for InventoryLotLine creation


+ 4
- 0
src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLineRepository.kt View File

@@ -3,6 +3,7 @@ package com.ffii.fpsms.modules.stock.entity
import com.ffii.core.support.AbstractRepository
import com.ffii.fpsms.modules.stock.entity.projection.QrCodeInfo
import com.ffii.fpsms.modules.stock.entity.projection.StockInLineInfo
import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository
import java.util.Optional

@@ -19,4 +20,7 @@ interface StockInLineRepository : AbstractRepository<StockInLine, Long> {
fun findAllByPurchaseOrderIdAndDeletedFalse(purchaseOrderId: Long): Optional<List<StockInLine>>
fun findStockInLineInfoByInventoryLotLineId(inventoryLotLineId: Long): Optional<StockInLineInfo>
fun findStockInLineInfoById(id: Long): Optional<StockInLineInfo>

@Query("SELECT sil FROM StockInLine sil WHERE sil.item.id = :itemId AND sil.deleted = false")
fun findAllByItemIdAndDeletedFalse(itemId: Long): List<StockInLine>
}

+ 29
- 1
src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt View File

@@ -46,7 +46,8 @@ import net.sf.jasperreports.engine.JasperExportManager
import net.sf.jasperreports.engine.JasperPrint
import java.io.File
import kotlin.jvm.optionals.getOrNull
import kotlin.math.max
import com.ffii.fpsms.modules.deliveryOrder.entity.DeliveryOrderRepository
import com.ffii.fpsms.modules.deliveryOrder.web.models.PrintQrCodeForDoRequest

@Serializable
data class QrContent(val itemId: Long, val stockInLineId: Long)
@@ -71,6 +72,7 @@ open class StockInLineService(
private val itemUomRepository: ItemUomRespository,
private val printerService: PrinterService,
private val stockTakeLineRepository: StockTakeLineRepository,
private val deliveryOrderRepository: DeliveryOrderRepository,
): AbstractBaseEntityService<StockInLine, Long, StockInLineRepository>(jdbcDao, stockInLineRepository) {

open fun getStockInLineInfo(stockInLineId: Long): StockInLineInfo {
@@ -577,4 +579,30 @@ open class StockInLineService(
tempPdfFile.delete()
}
}

@Transactional
open fun printQrCodeForDeliveryOrder(request: PrintQrCodeForDoRequest) {
// Get delivery order by ID
val deliveryOrder = deliveryOrderRepository.findByIdAndDeletedIsFalse(request.deliveryOrderId)
?: throw NoSuchElementException("Delivery order not found with ID: ${request.deliveryOrderId}")

// Loop through delivery order lines
deliveryOrder.deliveryOrderLines.forEach { deliveryOrderLine ->
val itemId = deliveryOrderLine.item?.id
?: throw IllegalStateException("Delivery order line ${deliveryOrderLine.id} has no item")

// Find all stock in lines matching this itemId
val stockInLines = stockInLineRepository.findAllByItemIdAndDeletedFalse(itemId)

// Print QR code for each stock in line
stockInLines.forEach { stockInLine ->
val printRequest = PrintQrCodeForSilRequest(
stockInLineId = stockInLine.id!!,
printerId = request.printerId,
printQty = request.printQty
)
printQrCode(printRequest)
}
}
}
}

+ 7
- 0
src/main/java/com/ffii/fpsms/modules/stock/web/model/PrintQrCodeForDoRequest.kt View File

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

data class PrintQrCodeForDoRequest(
val deliveryOrderId: Long,
val printerId: Long,
val printQty: Int?,
)

Loading…
Cancel
Save