Browse Source

[Warehouse, inventory, m18] import warehouse excel, update lot no genterator, update scheduler

master
cyril.tsui 2 months ago
parent
commit
700db33479
9 changed files with 121 additions and 20 deletions
  1. +1
    -1
      src/main/java/com/ffii/fpsms/m18/service/M18DeliveryOrderService.kt
  2. +4
    -4
      src/main/java/com/ffii/fpsms/modules/common/CodeGenerator.kt
  3. +5
    -5
      src/main/java/com/ffii/fpsms/modules/common/scheduler/service/SchedulerService.kt
  4. +60
    -2
      src/main/java/com/ffii/fpsms/modules/master/service/WarehouseService.kt
  5. +22
    -0
      src/main/java/com/ffii/fpsms/modules/master/web/WarehouseController.kt
  6. +5
    -0
      src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotRepository.kt
  7. +13
    -5
      src/main/java/com/ffii/fpsms/modules/stock/service/InventoryService.kt
  8. +10
    -1
      src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt
  9. +1
    -2
      src/main/java/com/ffii/fpsms/modules/stock/service/StockTakeService.kt

+ 1
- 1
src/main/java/com/ffii/fpsms/m18/service/M18DeliveryOrderService.kt View File

@@ -137,7 +137,7 @@ open class M18DeliveryOrderService(
// Process for Delivery Order (mainpo)
// Assume only one DO in the DO (search by DO ID)
val mainpo = deliveryOrderDetail?.data?.mainpo?.get(0)
logger.info("deliveryOrderDetail: data is null? ${deliveryOrderDetail?.data == null} | mainpo is null? ${deliveryOrderDetail?.data?.mainpo == null} | get(0) is null? ${deliveryOrderDetail?.data?.mainpo?.get(0) == null}")
// logger.info("deliveryOrderDetail: data is null? ${deliveryOrderDetail?.data == null} | mainpo is null? ${deliveryOrderDetail?.data?.mainpo == null} | get(0) is null? ${deliveryOrderDetail?.data?.mainpo?.get(0) == null}")
val pot = deliveryOrderDetail?.data?.pot
val deliveryOrderLineMessage = deliveryOrderDetail?.messages



+ 4
- 4
src/main/java/com/ffii/fpsms/modules/common/CodeGenerator.kt View File

@@ -4,7 +4,7 @@ import java.time.LocalDate
import java.time.format.DateTimeFormatter

object CodeGenerator {
// Default Value for Lot No
// Old Function
private var dateFormat = DateTimeFormatter.ofPattern("yyMMdd")
fun generateCode(prefix: String, itemId: Long, count: Int): String {
// prefix = "ITEM" || "LOT"
@@ -15,12 +15,12 @@ object CodeGenerator {
return "$prefix-$todayStr$itemStr$countStr"
}

// Default Value for Order No
val DEFAULT_SUFFIX_FORMAT = "%03d";
// Default Value for Order No & Lot No.
val DEFAULT_SUFFIX_FORMAT = "%04d";
val DEFAULT_PATTERN = "yyyyMMdd";
val DEFAULT_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_PATTERN)
val DEFAULT_MIDFIX = LocalDate.now().format(DEFAULT_FORMATTER)
fun generateOrderNo(
fun generateNo(
suffixFormat: String? = null,
pattern: String? = null,
prefix: String,


+ 5
- 5
src/main/java/com/ffii/fpsms/modules/common/scheduler/service/SchedulerService.kt View File

@@ -74,7 +74,7 @@ open class SchedulerService(
// Init Scheduler
// @PostConstruct
fun init() {
scheduleM18PoTask();
// scheduleM18PoTask();
scheduleM18MasterData();
scheduleRoughProd();
scheduleDetailedProd();
@@ -160,8 +160,8 @@ open class SchedulerService(
)
m18PurchaseOrderService.savePurchaseOrders(request);
m18DeliveryOrderService.saveDeliveryOrders(request);
logger.info("today: ${today.format(dataStringFormat)}")
logger.info("yesterday: ${yesterday.format(dataStringFormat)}")
// logger.info("today: ${today.format(dataStringFormat)}")
// logger.info("yesterday: ${yesterday.format(dataStringFormat)}")
}

open fun getM18MasterData() {
@@ -179,7 +179,7 @@ open class SchedulerService(
m18MasterDataService.saveVendors(request)
m18MasterDataService.saveBusinessUnits(request)
m18MasterDataService.saveCurrencies(request)
logger.info("today: ${today.format(dataStringFormat)}")
logger.info("yesterday: ${yesterday.format(dataStringFormat)}")
// logger.info("today: ${today.format(dataStringFormat)}")
// logger.info("yesterday: ${yesterday.format(dataStringFormat)}")
}
}

+ 60
- 2
src/main/java/com/ffii/fpsms/modules/master/service/WarehouseService.kt View File

@@ -2,6 +2,8 @@ package com.ffii.fpsms.modules.master.service

import com.ffii.core.support.AbstractBaseEntityService
import com.ffii.core.support.JdbcDao
import com.ffii.core.utils.ExcelUtils
import com.ffii.core.utils.JwtTokenUtil
import com.ffii.fpsms.modules.master.entity.ItemsRepository
import com.ffii.fpsms.modules.master.entity.Warehouse
import com.ffii.fpsms.modules.master.entity.WarehouseRepository
@@ -14,15 +16,19 @@ import com.ffii.fpsms.modules.stock.entity.StockInLineRepository
import com.ffii.fpsms.modules.stock.entity.StockInRepository
import com.ffii.fpsms.modules.stock.service.InventoryLotService
import com.ffii.fpsms.modules.stock.service.StockInService
import org.apache.poi.ss.usermodel.Sheet
import org.apache.poi.ss.usermodel.Workbook
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import java.math.BigDecimal
import kotlin.jvm.optionals.getOrNull

@Service
open class WarehouseService(
private val jdbcDao: JdbcDao,
private val warehouseRepository: WarehouseRepository,
): AbstractBaseEntityService<Warehouse, Long, WarehouseRepository>(jdbcDao, warehouseRepository) {

) : AbstractBaseEntityService<Warehouse, Long, WarehouseRepository>(jdbcDao, warehouseRepository) {
open fun getWarehouses(): List<Warehouse> {
return warehouseRepository.findAll().filter { it.deleted == false }
}
@@ -51,4 +57,56 @@ open class WarehouseService(

return warehouseRepository.save(warehouse);
}

open fun importExcel(workbook: Workbook?): String {
logger.info("--------- Start - Import Warehouse Excel -------");

if (workbook == null) {
logger.error("No Excel Import");
return "Import Excel failure";
}
val sheet: Sheet = workbook.getSheetAt(0);

// Columns
val COLUMN_WAREHOSE_INDEX = 1;
val COLUMN_ZONE_INDEX = 2;
val COLUMN_SLOT_INDEX = 3;
val COLUMN_FLOOR_INDEX = 4;
val COLUMN_PLACE_INDEX = 5;

val START_ROW_INDEX = 2;

// Start Import
for (i in START_ROW_INDEX..<sheet.lastRowNum) {
val row = sheet.getRow(i)

try {
val floor = ExcelUtils.getStringValue(row.getCell(COLUMN_FLOOR_INDEX)).trim()
val place = ExcelUtils.getStringValue(row.getCell(COLUMN_PLACE_INDEX)).trim()
val code = ExcelUtils.getStringValue(row.getCell(COLUMN_WAREHOSE_INDEX)).trim()
val zone = ExcelUtils.getStringValue(row.getCell(COLUMN_ZONE_INDEX)).trim()
val slot = ExcelUtils.getStringValue(row.getCell(COLUMN_SLOT_INDEX)).trim()
// logger.info("Warehouse code - zone - slot: ${row.getCell(COLUMN_WAREHOSE_INDEX).cellType} - ${row.getCell(COLUMN_ZONE_INDEX).cellType} - ${row.getCell(COLUMN_SLOT_INDEX).cellType}")

val defaultCapacity = BigDecimal(10000)
val warehouseCode = "$code-$zone-$slot"
val warehouseName = "$floor-$place"
val existingWarehouse = findByCode(warehouseCode)

if (existingWarehouse == null) {
val warehouseRequest = SaveWarehouseRequest(
code = warehouseCode,
name = warehouseName,
description = warehouseName,
capacity = defaultCapacity
)
saveWarehouse(warehouseRequest)
}
} catch (e: Exception) {
logger.error("Import Error (Warehouse Error): ${e.message}")
}
}
logger.info("--------- End - Import Warehouse Excel -------")
return "Import Excel success";
}
}

+ 22
- 0
src/main/java/com/ffii/fpsms/modules/master/web/WarehouseController.kt View File

@@ -3,9 +3,16 @@ package com.ffii.fpsms.modules.master.web
import com.ffii.fpsms.modules.master.entity.Warehouse
import com.ffii.fpsms.modules.master.entity.projections.WarehouseCombo
import com.ffii.fpsms.modules.master.service.WarehouseService
import jakarta.servlet.http.HttpServletRequest
import org.apache.poi.ss.usermodel.Workbook
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.ServletRequestBindingException
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartHttpServletRequest

@RestController
@RequestMapping("/warehouse")
@@ -21,4 +28,19 @@ class WarehouseController(
fun findCombo(): List<WarehouseCombo> {
return warehouseService.findCombo()
}

@PostMapping("/import")
@Throws(ServletRequestBindingException::class)
fun importExcel(request: HttpServletRequest): ResponseEntity<*> {
var workbook: Workbook? = null;

try {
val multipartFile = (request as MultipartHttpServletRequest).getFile("multipartFileList")
workbook = XSSFWorkbook(multipartFile?.inputStream)
} catch (e: Exception) {
println(e)
}

return ResponseEntity.ok(warehouseService.importExcel(workbook))
}
}

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

@@ -1,6 +1,7 @@
package com.ffii.fpsms.modules.stock.entity

import com.ffii.core.support.AbstractRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository
import java.io.Serializable

@@ -10,4 +11,8 @@ interface InventoryLotRepository: AbstractRepository<InventoryLot, Long> {

fun findByItemIdAndDeletedFalse(itemId: Long): List<InventoryLot>

@Query("""
select il.lotNo from InventoryLot il where il.lotNo like :prefix% order by il.lotNo desc limit 1
""")
fun findLatestLotNoByPrefix(prefix: String): String?
}

+ 13
- 5
src/main/java/com/ffii/fpsms/modules/stock/service/InventoryService.kt View File

@@ -81,6 +81,13 @@ open class InventoryService(
return inventoryRepository.findInventoryInfoByItemIdInAndDeletedIsFalse(itemIds);
}

open fun assignLotNo(): String {
val prefix = "LT"
val midfix = CodeGenerator.DEFAULT_MIDFIX
val latestCode = inventoryLotRepository.findLatestLotNoByPrefix("${prefix}-${midfix}")
return CodeGenerator.generateNo(prefix = prefix, latestCode = latestCode)
}

fun save_po(): PurchaseOrder {
val poCode = "MANUAL-IMPORT ${LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE)}"
val po = PurchaseOrder().apply {
@@ -269,11 +276,12 @@ open class InventoryService(
// stock in line
val oneYearExpiry = 1L
val stockInLineEntries = polList.map { pol ->
val newLotNo = CodeGenerator.generateCode(
prefix = "MPO",
itemId = pol.item!!.id!!,
count = pol.id!!.toInt()
)
// val newLotNo = CodeGenerator.generateCode(
// prefix = "MPO",
// itemId = pol.item!!.id!!,
// count = pol.id!!.toInt()
// )
val newLotNo = assignLotNo()
StockInLine().apply {
this.purchaseOrder = po
this.purchaseOrderLine = pol


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

@@ -79,6 +79,14 @@ open class StockInLineService(
open fun getReceivedStockInLineInfo(stockInLineId: Long): StockInLineInfo {
return stockInLineRepository.findStockInLineInfoByIdAndStatusAndDeletedFalse(id = stockInLineId, status = StockInLineStatus.RECEIVED.status).orElseThrow()
}

open fun assignLotNo(): String {
val prefix = "LT"
val midfix = CodeGenerator.DEFAULT_MIDFIX
val latestCode = inventoryLotRepository.findLatestLotNoByPrefix("${prefix}-${midfix}")
return CodeGenerator.generateNo(prefix = prefix, latestCode = latestCode)
}

@Throws(IOException::class)
@Transactional
open fun create(request: SaveStockInLineRequest): MessageResponse {
@@ -179,7 +187,8 @@ open class StockInLineService(
"itemId" to stockInLine.item!!.id
)
val inventoryCount = jdbcDao.queryForInt(INVENTORY_COUNT.toString(), args)
val newLotNo = CodeGenerator.generateCode(prefix = "MPO", itemId = stockInLine.item!!.id!!, count = inventoryCount)
// val newLotNo = CodeGenerator.generateCode(prefix = "MPO", itemId = stockInLine.item!!.id!!, count = inventoryCount)
val newLotNo = assignLotNo()
inventoryLot.apply {
this.item = stockInLine.item
this.stockInLine = stockInLine


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

@@ -21,7 +21,6 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import java.math.BigDecimal
import java.time.LocalDate
import java.time.LocalDateTime

@Service
@@ -42,7 +41,7 @@ class StockTakeService(
val prefix = "ST"
val midfix = CodeGenerator.DEFAULT_MIDFIX
val latestCode = stockTakeRepository.findLatestCodeByPrefix("${prefix}-${midfix}")
return CodeGenerator.generateOrderNo(prefix = prefix, latestCode = latestCode)
return CodeGenerator.generateNo(prefix = prefix, latestCode = latestCode)
}

fun saveStockTake(request: SaveStockTakeRequest): StockTake {


Loading…
Cancel
Save