@@ -1,19 +1,23 @@ | |||||
package com.ffii.fpsms.modules.pickOrder.service | package com.ffii.fpsms.modules.pickOrder.service | ||||
import com.ffii.core.response.RecordsRes | import com.ffii.core.response.RecordsRes | ||||
import com.ffii.core.support.AbstractBaseEntityService | |||||
import com.ffii.core.support.JdbcDao | import com.ffii.core.support.JdbcDao | ||||
import com.ffii.fpsms.modules.common.SecurityUtils | import com.ffii.fpsms.modules.common.SecurityUtils | ||||
import com.ffii.fpsms.modules.pickOrder.entity.PickOrder | |||||
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository | import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository | ||||
import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderInfo | import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderInfo | ||||
import com.ffii.fpsms.modules.pickOrder.enums.PickOrderStatus | import com.ffii.fpsms.modules.pickOrder.enums.PickOrderStatus | ||||
import com.ffii.fpsms.modules.pickOrder.web.models.* | import com.ffii.fpsms.modules.pickOrder.web.models.* | ||||
import com.ffii.fpsms.modules.stock.entity.InventoryLotLineRepository | import com.ffii.fpsms.modules.stock.entity.InventoryLotLineRepository | ||||
import com.ffii.fpsms.modules.stock.entity.StockOut | import com.ffii.fpsms.modules.stock.entity.StockOut | ||||
import com.ffii.fpsms.modules.stock.entity.StockOutLIneRepository | |||||
import com.ffii.fpsms.modules.stock.entity.StockOutRepository | import com.ffii.fpsms.modules.stock.entity.StockOutRepository | ||||
import com.ffii.fpsms.modules.stock.entity.projection.CurrentInventoryItemInfo | import com.ffii.fpsms.modules.stock.entity.projection.CurrentInventoryItemInfo | ||||
import com.ffii.fpsms.modules.stock.service.InventoryService | import com.ffii.fpsms.modules.stock.service.InventoryService | ||||
import com.ffii.fpsms.modules.stock.service.StockOutLineService | import com.ffii.fpsms.modules.stock.service.StockOutLineService | ||||
import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService | import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService | ||||
import com.ffii.fpsms.modules.stock.web.model.StockOutLineStatus | |||||
import com.ffii.fpsms.modules.stock.web.model.StockOutStatus | import com.ffii.fpsms.modules.stock.web.model.StockOutStatus | ||||
import com.ffii.fpsms.modules.stock.web.model.SuggestedPickLotForPoRequest | import com.ffii.fpsms.modules.stock.web.model.SuggestedPickLotForPoRequest | ||||
import com.ffii.fpsms.modules.user.entity.UserRepository | import com.ffii.fpsms.modules.user.entity.UserRepository | ||||
@@ -23,6 +27,7 @@ import org.springframework.http.HttpStatus | |||||
import org.springframework.http.ResponseEntity | import org.springframework.http.ResponseEntity | ||||
import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
import org.springframework.transaction.annotation.Transactional | import org.springframework.transaction.annotation.Transactional | ||||
import java.io.IOException | |||||
import java.io.Serializable | import java.io.Serializable | ||||
import java.math.BigDecimal | import java.math.BigDecimal | ||||
import java.time.LocalDate | import java.time.LocalDate | ||||
@@ -34,13 +39,13 @@ import kotlin.jvm.optionals.getOrNull | |||||
open class PickOrderService( | open class PickOrderService( | ||||
private val jdbcDao: JdbcDao, | private val jdbcDao: JdbcDao, | ||||
val pickOrderRepository: PickOrderRepository, | val pickOrderRepository: PickOrderRepository, | ||||
val stockOutLineService: StockOutLineService, | |||||
val suggestedPickLotService: SuggestedPickLotService, | val suggestedPickLotService: SuggestedPickLotService, | ||||
val userService: UserService, | val userService: UserService, | ||||
private val stockOutLIneRepository: StockOutLIneRepository, | |||||
private val inventoryLotLineRepository: InventoryLotLineRepository, | private val inventoryLotLineRepository: InventoryLotLineRepository, | ||||
val inventoryService: InventoryService, | val inventoryService: InventoryService, | ||||
private val stockOutRepository: StockOutRepository | private val stockOutRepository: StockOutRepository | ||||
) { | |||||
): AbstractBaseEntityService<PickOrder, Long, PickOrderRepository>(jdbcDao, pickOrderRepository) { | |||||
open fun localDateTimeParse(dateTime: String?, pattern: String? = "YYYY-MM-DD hh:mm:ss"): LocalDateTime? { | open fun localDateTimeParse(dateTime: String?, pattern: String? = "YYYY-MM-DD hh:mm:ss"): LocalDateTime? { | ||||
try { | try { | ||||
val formatter = DateTimeFormatter.ofPattern(pattern!!) | val formatter = DateTimeFormatter.ofPattern(pattern!!) | ||||
@@ -424,4 +429,30 @@ open class PickOrderService( | |||||
return releaseConsoPickOrderInfo(request.consoCode) | return releaseConsoPickOrderInfo(request.consoCode) | ||||
} | } | ||||
@Throws(IOException::class) | |||||
@Transactional | |||||
open fun completeStockOut(consoCode: String): Boolean { | |||||
val stockOut = stockOutRepository.findByConsoPickOrderCode(consoCode).orElseThrow() | |||||
val stockOutLines = stockOutLIneRepository.findAllByStockOutId(stockOut.id!!) | |||||
val unfinishedLines = stockOutLines.filter { | |||||
it.status != StockOutLineStatus.COMPLETE.status | |||||
&& it.status != StockOutLineStatus.REJECTED.status | |||||
} | |||||
if (unfinishedLines.isEmpty()) { | |||||
stockOut.apply { | |||||
this.status = StockOutStatus.COMPLETE.status | |||||
} | |||||
stockOutRepository.save(stockOut) | |||||
val pickOrderEntries = pickOrderRepository.findAllByConsoCode(consoCode).map { | |||||
it.apply { | |||||
it.status = PickOrderStatus.COMPLETED | |||||
} | |||||
} | |||||
pickOrderRepository.saveAll(pickOrderEntries) | |||||
return true | |||||
} else { | |||||
return false | |||||
} | |||||
} | |||||
} | } |
@@ -101,4 +101,10 @@ class PickOrderController( | |||||
fun pickConsoPickOrderInfo(@PathVariable consoCode: String): ReleasePickOrderInfoResponse { | fun pickConsoPickOrderInfo(@PathVariable consoCode: String): ReleasePickOrderInfoResponse { | ||||
return pickOrderService.releaseConsoPickOrderInfo(consoCode); | return pickOrderService.releaseConsoPickOrderInfo(consoCode); | ||||
} | } | ||||
@PostMapping("/consoPickOrder/complete/{consoCode}") | |||||
fun completeConsoPickOrders(@PathVariable consoCode: String): Boolean { | |||||
return pickOrderService.completeStockOut(consoCode) | |||||
} | |||||
} | } |
@@ -14,4 +14,6 @@ interface StockOutLIneRepository: AbstractRepository<StockOutLine, Long> { | |||||
fun findAllByIdIn(id: List<Long>): List<StockOutLineInfo> | fun findAllByIdIn(id: List<Long>): List<StockOutLineInfo> | ||||
fun findStockOutLineInfoById(id: Long): StockOutLineInfo | fun findStockOutLineInfoById(id: Long): StockOutLineInfo | ||||
fun findAllByStockOutId(stockOutId: Long): List<StockOutLine> | |||||
} | } |
@@ -5,6 +5,8 @@ import com.ffii.core.support.JdbcDao | |||||
import com.ffii.fpsms.modules.master.entity.Items | import com.ffii.fpsms.modules.master.entity.Items | ||||
import com.ffii.fpsms.modules.master.entity.ItemsRepository | import com.ffii.fpsms.modules.master.entity.ItemsRepository | ||||
import com.ffii.fpsms.modules.master.web.models.MessageResponse | import com.ffii.fpsms.modules.master.web.models.MessageResponse | ||||
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository | |||||
import com.ffii.fpsms.modules.pickOrder.enums.PickOrderStatus | |||||
import com.ffii.fpsms.modules.stock.entity.* | import com.ffii.fpsms.modules.stock.entity.* | ||||
import com.ffii.fpsms.modules.stock.web.model.SaveStockOutRequest | import com.ffii.fpsms.modules.stock.web.model.SaveStockOutRequest | ||||
import com.ffii.fpsms.modules.stock.web.model.StockOutLineStatus | import com.ffii.fpsms.modules.stock.web.model.StockOutLineStatus | ||||
@@ -18,79 +20,11 @@ import java.time.LocalDateTime | |||||
@Service | @Service | ||||
open class StockOutService( | open class StockOutService( | ||||
private val jdbcDao: JdbcDao, | private val jdbcDao: JdbcDao, | ||||
private val pickOrderRepository: PickOrderRepository, | |||||
private val stockOutRepository: StockOutRepository, | private val stockOutRepository: StockOutRepository, | ||||
private val stockOutLIneRepository: StockOutLIneRepository, | private val stockOutLIneRepository: StockOutLIneRepository, | ||||
private val stockOutLineService: StockOutLineService, | private val stockOutLineService: StockOutLineService, | ||||
private val stockLedgerRepository: StockLedgerRepository, | private val stockLedgerRepository: StockLedgerRepository, | ||||
): AbstractBaseEntityService<StockOut, Long, StockOutRepository>(jdbcDao, stockOutRepository) { | ): AbstractBaseEntityService<StockOut, Long, StockOutRepository>(jdbcDao, stockOutRepository) { | ||||
@Throws(IOException::class) | |||||
@Transactional | |||||
open fun complete(request: SaveStockOutRequest): MessageResponse { | |||||
if (request.id === null) { | |||||
return MessageResponse( | |||||
id = null, | |||||
code = null, | |||||
name = null, | |||||
type = null, | |||||
message = "id cannot be null", | |||||
errorPosition = "id" | |||||
) | |||||
} | |||||
/// checking pick quantity | |||||
val stockOut = stockOutRepository.findById(request.id).orElseThrow() | |||||
val allLines = stockOutLineService.findAllByStockOutId(request.id) | |||||
val isBalanced = allLines.all{ | |||||
val status = it.status | |||||
var sum = 0.0 | |||||
when (status) { | |||||
StockOutLineStatus.PENDING.status -> sum += it.qty ?: 0.0; | |||||
// StockOutLineStatus.PICKED.status -> sum -= it.qty ?: 0.0; | |||||
} | |||||
sum == 0.0 | |||||
} | |||||
if (!isBalanced) { | |||||
return MessageResponse( | |||||
id = request.id, | |||||
code = "stockOut.consoCode", | |||||
name = "stockOut.pickOrderCode ?: stockOut.deliveryOrderCode", | |||||
type = stockOut.type, | |||||
message = "there are items not picked", | |||||
errorPosition = null | |||||
) | |||||
} | |||||
// remove base record | |||||
val baseLines = allLines.filter { stockOutLine -> stockOutLine.status === StockOutLineStatus.PENDING.status} | |||||
// update pick record to complete | |||||
val pickLines = allLines | |||||
// .filter { stockOutLine -> stockOutLine.status === StockOutLineStatus.PICKED.status} | |||||
.map { stockOutLine -> | |||||
stockOutLine.apply { | |||||
status = StockOutLineStatus.COMPLETE.status | |||||
} | |||||
} | |||||
// write ledger | |||||
val ledgers = pickLines.map {stockOutLine -> | |||||
StockLedger().apply { | |||||
this.stockOutLine = stockOutLine | |||||
// this.inventory = stockOutLine.inventory | |||||
outQty = stockOutLine.qty | |||||
} | |||||
} | |||||
stockLedgerRepository.saveAll(ledgers) | |||||
stockOutLIneRepository.deleteAll(baseLines) | |||||
stockOutLIneRepository.saveAll(pickLines) | |||||
stockOut.apply { | |||||
completeDate = LocalDateTime.now() | |||||
status = StockOutStatus.COMPLETE.status | |||||
} | |||||
val savedStockOut = stockOutRepository.saveAndFlush(stockOut) | |||||
return MessageResponse( | |||||
id = savedStockOut.id, | |||||
code = "savedStockOut.consoCode", | |||||
name = "savedStockOut.pickOrderCode ?: savedStockOut.deliveryOrderCode", | |||||
type = savedStockOut.type, | |||||
message = "stock out completed", | |||||
errorPosition = null | |||||
) | |||||
} | |||||
} | } |
@@ -0,0 +1,12 @@ | |||||
package com.ffii.fpsms.modules.stock.web | |||||
import com.ffii.fpsms.modules.stock.service.StockOutService | |||||
import org.springframework.web.bind.annotation.RequestMapping | |||||
import org.springframework.web.bind.annotation.RestController | |||||
@RestController | |||||
@RequestMapping("/stockOut") | |||||
class StockOutController( | |||||
private val stockOutService: StockOutService | |||||
) { | |||||
} |