@@ -2,6 +2,7 @@ package com.ffii.fpsms.modules.purchaseOrder.entity | |||
import com.ffii.core.support.AbstractRepository | |||
import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PurchaseOrderLineInfo | |||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus | |||
import org.springframework.stereotype.Repository | |||
import java.io.Serializable | |||
@@ -10,6 +11,6 @@ interface PurchaseOrderLineRepository : AbstractRepository<PurchaseOrderLine, Lo | |||
fun findByM18DataLogIdAndDeletedIsFalse(m18datalogId: Serializable): PurchaseOrderLine? | |||
fun findAllPurchaseOrderLineInfoByPurchaseOrderIdAndDeletedIsFalse(purchaseOrderId: Long): List<PurchaseOrderLineInfo> | |||
fun findAllByPurchaseOrderIdAndDeletedIsFalse(purchaseOrderId: Long): List<PurchaseOrderLine> | |||
// fun find | |||
fun findAllByPurchaseOrderIdAndStatusNotAndDeletedIsFalse(purchaseOrderId: Long, status: PurchaseOrderLineStatus): List<PurchaseOrderLine> | |||
// fun find | |||
} |
@@ -6,11 +6,13 @@ import com.ffii.fpsms.m18.entity.M18DataLogRepository | |||
import com.ffii.fpsms.modules.master.entity.ShopRepository | |||
import com.ffii.fpsms.modules.master.service.CurrencyService | |||
import com.ffii.fpsms.modules.master.service.ShopService | |||
import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrder | |||
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLineRepository | |||
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderRepository | |||
import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PoLineWithStockInLine | |||
import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PurchaseOrderInfo | |||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus | |||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus | |||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType | |||
import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderRequest | |||
@@ -131,5 +133,38 @@ open class PurchaseOrderService( | |||
return savedPurchaseOrder | |||
} | |||
fun checkPolAndCompletePo(id: Long): MessageResponse { | |||
val unfinishedLines = purchaseOrderLineRepository | |||
.findAllByPurchaseOrderIdAndStatusNotAndDeletedIsFalse( | |||
purchaseOrderId = id, | |||
status = PurchaseOrderLineStatus.COMPLETED | |||
) | |||
val po = purchaseOrderRepository.findById(id).orElseThrow() | |||
if (unfinishedLines.isEmpty()) { | |||
po.apply { | |||
status = PurchaseOrderStatus.COMPLETED | |||
} | |||
val savedPo = purchaseOrderRepository.saveAndFlush(po) | |||
return MessageResponse( | |||
id = savedPo.id, | |||
name = savedPo.code, | |||
code = savedPo.code, | |||
type = PurchaseOrderStatus.COMPLETED.value, | |||
message = "Update Success", | |||
errorPosition = null, | |||
entity = savedPo, | |||
) | |||
} | |||
val unfinishedIds = unfinishedLines.map { it.id } | |||
return MessageResponse( | |||
id = po.id, | |||
name = po.code, | |||
code = null, | |||
type = PurchaseOrderStatus.RECEIVING.value, | |||
message = "Still have unfinished po lines", | |||
errorPosition = "Unfinished", | |||
entity = unfinishedIds, | |||
) | |||
} | |||
} |
@@ -3,13 +3,11 @@ package com.ffii.fpsms.modules.purchaseOrder.web | |||
import com.ffii.core.support.JdbcDao | |||
import com.ffii.fpsms.modules.master.entity.Items | |||
import com.ffii.fpsms.modules.master.service.ItemsService | |||
import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrder | |||
import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PurchaseOrderInfo | |||
import com.ffii.fpsms.modules.purchaseOrder.service.PurchaseOrderService | |||
import org.springframework.web.bind.annotation.GetMapping | |||
import org.springframework.web.bind.annotation.PathVariable | |||
import org.springframework.web.bind.annotation.RequestMapping | |||
import org.springframework.web.bind.annotation.RestController | |||
import org.springframework.web.bind.annotation.* | |||
@RestController | |||
@RequestMapping("/po") | |||
@@ -20,8 +18,13 @@ class PurchaseOrderController( | |||
fun getPoList(): List<PurchaseOrderInfo> { | |||
return purchaseOrderService.getPoList() | |||
} | |||
@GetMapping("/detail/{id}") | |||
@GetMapping("/detail/{id}") // purchaseOrderId | |||
fun getDetailedPo(@PathVariable id: Long): Map<String, Any> { | |||
return purchaseOrderService.getDetailedPo(id) | |||
} | |||
@PostMapping("/check/{id}") // purchaseOrderId | |||
fun checkPolAndCompletePo(@PathVariable id: Long): MessageResponse { | |||
return purchaseOrderService.checkPolAndCompletePo(id) | |||
} | |||
} |
@@ -4,6 +4,8 @@ import org.springframework.beans.factory.annotation.Value | |||
interface QcResultInfo { | |||
val id: Long | |||
@get:Value("#{target.qcItem.id}") | |||
val qcItemId: Long | |||
@get:Value("#{target.qcItem.name}") | |||
val name: String | |||
@get:Value("#{target.qcItem.code}") | |||
@@ -11,4 +11,5 @@ interface StockInLineRepository : AbstractRepository<StockInLine, Long> { | |||
fun findAllStockInLineInfoByStockInIdAndDeletedFalse(stockInId: Long): List<StockInLineInfo> | |||
fun findStockInLineInfoByIdAndDeletedFalse(id: Long): StockInLineInfo | |||
fun findStockInLineInfoByIdInAndDeletedFalse(id: List<Long>): List<StockInLineInfo> | |||
fun findStockInLineInfoByPurchaseOrderLineIdAndStatusNotAndDeletedFalse(purchaseOrderLineId: Long, status: String): List<StockInLineInfo> | |||
} |
@@ -2,7 +2,6 @@ package com.ffii.fpsms.modules.stock.service | |||
import com.ffii.core.support.AbstractBaseEntityService | |||
import com.ffii.core.support.JdbcDao | |||
import com.ffii.core.utils.JsonUtils | |||
import com.ffii.core.utils.QrCodeUtil | |||
import com.ffii.fpsms.modules.common.CodeGenerator | |||
import com.ffii.fpsms.modules.master.entity.ItemsRepository | |||
@@ -27,6 +26,10 @@ import java.time.LocalDate | |||
import java.time.LocalDateTime | |||
import com.ffii.core.utils.PdfUtils; | |||
import com.ffii.fpsms.modules.master.entity.WarehouseRepository | |||
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderRepository | |||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus | |||
import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus | |||
import com.ffii.fpsms.modules.stock.entity.projection.StockInLineInfo | |||
import java.io.FileNotFoundException | |||
import java.time.format.DateTimeFormatter | |||
import kotlinx.serialization.Serializable | |||
@@ -39,6 +42,7 @@ data class QrContent(val itemId: Long, val stockInLineId: Long) | |||
@Service | |||
open class StockInLineService( | |||
private val jdbcDao: JdbcDao, | |||
private val purchaseOrderRepository: PurchaseOrderRepository, | |||
private val polRepository: PurchaseOrderLineRepository, | |||
private val qcItemsRepository: QcItemRepository, | |||
private val qcResultRepository: QcResultRepository, | |||
@@ -51,6 +55,9 @@ open class StockInLineService( | |||
private val warehouseRepository: WarehouseRepository, | |||
): AbstractBaseEntityService<StockInLine, Long, StockInLineRepository>(jdbcDao, stockInLineRepository) { | |||
open fun getStockInLineInfo(stockInLineId: Long): StockInLineInfo { | |||
return stockInLineRepository.findStockInLineInfoByIdAndDeletedFalse(stockInLineId) | |||
} | |||
@Throws(IOException::class) | |||
@Transactional | |||
open fun create(request: SaveStockInLineRequest): MessageResponse { | |||
@@ -136,6 +143,44 @@ open class StockInLineService( | |||
} | |||
return null | |||
} | |||
@Throws(IOException::class) | |||
@Transactional | |||
fun updatePurchaseOrderStatus(request: SaveStockInLineRequest) { | |||
if (request.status == StockInLineStatus.COMPLETE.status) { | |||
val unfinishedLines = polRepository.findAllByPurchaseOrderIdAndStatusNotAndDeletedIsFalse( | |||
purchaseOrderId = request.purchaseOrderId, | |||
status = PurchaseOrderLineStatus.COMPLETED | |||
) | |||
if (unfinishedLines.isEmpty()) { | |||
val po = purchaseOrderRepository.findById(request.purchaseOrderId).orElseThrow() | |||
po.apply { | |||
status = PurchaseOrderStatus.COMPLETED | |||
} | |||
purchaseOrderRepository.saveAndFlush(po) | |||
} else { | |||
} | |||
} | |||
} | |||
@Throws(IOException::class) | |||
@Transactional | |||
fun updatePurchaseOrderLineStatus(request: SaveStockInLineRequest) { | |||
if (request.status == StockInLineStatus.COMPLETE.status) { | |||
val unfinishedLines = stockInLineRepository.findStockInLineInfoByPurchaseOrderLineIdAndStatusNotAndDeletedFalse(purchaseOrderLineId = request.purchaseOrderLineId, status = request.status!!) | |||
if (unfinishedLines.isEmpty()) { | |||
// all stock in lines finished | |||
// change status of purchase order line | |||
val purchaseOrderLine = polRepository.findById(request.purchaseOrderLineId).orElseThrow() | |||
purchaseOrderLine.apply { | |||
status = PurchaseOrderLineStatus.COMPLETED | |||
} | |||
polRepository.saveAndFlush(purchaseOrderLine) | |||
} else { | |||
// still have unfinished lines | |||
} | |||
} | |||
} | |||
@Throws(IOException::class) | |||
@Transactional | |||
open fun update(request: SaveStockInLineRequest): MessageResponse { | |||
@@ -164,6 +209,7 @@ open class StockInLineService( | |||
if (request.status == StockInLineStatus.COMPLETE.status) { | |||
savedInventoryLotLine = saveInventoryLotLineWhenStockIn(request = request, stockInLine = stockInLine) | |||
} | |||
// println("checkpoint1") | |||
stockInLine.apply { | |||
// user = null | |||
this.productionDate = request.productionDate?.atStartOfDay() // maybe need to change the request to LocalDateTime | |||
@@ -175,7 +221,12 @@ open class StockInLineService( | |||
this.lotNo = stockInLine.lotNo ?: savedInventoryLot?.lotNo | |||
} | |||
val savedStockInLine = saveAndFlush(stockInLine) | |||
// check if all line completed | |||
updatePurchaseOrderLineStatus(request) | |||
updatePurchaseOrderStatus(request) | |||
// val allLineByStockInId = find | |||
val lineInfo = stockInLineRepository.findStockInLineInfoByIdAndDeletedFalse(savedStockInLine.id!!) | |||
// println("checkpoint2") | |||
return MessageResponse( | |||
id = savedStockInLine.id, | |||
code = null, | |||
@@ -196,6 +247,11 @@ open class StockInLineService( | |||
errorPosition = "request.acceptedQty", | |||
) | |||
} | |||
// var newLineAcceptedQty = 0.0 | |||
// if (request.rejectQty != null && request.rejectQty!! > BigDecimal.ZERO) { | |||
// | |||
// } | |||
val newStockInLine = StockInLine() | |||
newStockInLine.apply { | |||
this.item = stockInLine.item | |||
@@ -237,6 +293,9 @@ open class StockInLineService( | |||
val savedEntries = stockInLineRepository.saveAllAndFlush(stockInLineEntries) | |||
val ids = savedEntries.map { it.id!! } | |||
val lineInfoList = stockInLineRepository.findStockInLineInfoByIdInAndDeletedFalse(ids) | |||
// check if all line completed | |||
updatePurchaseOrderLineStatus(request) | |||
updatePurchaseOrderStatus(request) | |||
return MessageResponse( | |||
id = stockInLine.id, | |||
@@ -291,5 +350,4 @@ open class StockInLineService( | |||
"fileName" to qrCodeInfo[0].poCode | |||
); | |||
} | |||
} |
@@ -1,6 +1,9 @@ | |||
package com.ffii.fpsms.modules.stock.web | |||
import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||
import com.ffii.fpsms.modules.qc.entity.projection.QcResultInfo | |||
import com.ffii.fpsms.modules.stock.entity.StockInLine | |||
import com.ffii.fpsms.modules.stock.entity.projection.StockInLineInfo | |||
import com.ffii.fpsms.modules.stock.service.StockInLineService | |||
import com.ffii.fpsms.modules.stock.web.model.ExportQrCodeRequest | |||
import com.ffii.fpsms.modules.stock.web.model.SaveStockInLineRequest | |||
@@ -9,10 +12,7 @@ import jakarta.validation.Valid | |||
import net.sf.jasperreports.engine.JasperExportManager | |||
import net.sf.jasperreports.engine.JasperPrint | |||
import org.springframework.context.NoSuchMessageException | |||
import org.springframework.web.bind.annotation.PostMapping | |||
import org.springframework.web.bind.annotation.RequestBody | |||
import org.springframework.web.bind.annotation.RequestMapping | |||
import org.springframework.web.bind.annotation.RestController | |||
import org.springframework.web.bind.annotation.* | |||
import java.io.OutputStream | |||
import java.io.UnsupportedEncodingException | |||
import java.text.ParseException | |||
@@ -23,6 +23,10 @@ import java.text.ParseException | |||
class StockInLineController( | |||
private val stockInLineService: StockInLineService | |||
) { | |||
@GetMapping("/{stockInLineId}") | |||
fun get(@PathVariable stockInLineId: Long): StockInLineInfo { | |||
return stockInLineService.getStockInLineInfo(stockInLineId) | |||
} | |||
@PostMapping("/create") | |||
fun create(@Valid @RequestBody newItem: SaveStockInLineRequest): MessageResponse { | |||
return stockInLineService.create(newItem) | |||
@@ -47,5 +47,6 @@ data class SaveStockInLineRequest( | |||
var receiptDate: LocalDate?, | |||
var productionDate: LocalDate?, | |||
var qcResult: List<SaveQcResultRequest>?, | |||
var warehouseId: Long? | |||
var warehouseId: Long?, | |||
var rejectQty: BigDecimal? | |||
) |