diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLine.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLine.kt index eaf7b9b..a996f68 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLine.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLine.kt @@ -1,8 +1,11 @@ package com.ffii.fpsms.modules.stock.entity import com.ffii.core.entity.BaseEntity +import com.ffii.fpsms.modules.master.entity.Warehouse import jakarta.persistence.Column import jakarta.persistence.Entity +import jakarta.persistence.JoinColumn +import jakarta.persistence.ManyToOne import jakarta.persistence.Table import jakarta.validation.constraints.NotNull import org.hibernate.annotations.JdbcTypeCode @@ -12,24 +15,32 @@ import java.math.BigDecimal @Entity @Table(name = "inventory_lot_line") open class InventoryLotLine : BaseEntity() { + @NotNull + @ManyToOne + @JoinColumn(name = "inventoryLotId") + open var inventoryLot: InventoryLot? = null @NotNull + @ManyToOne + @JoinColumn(name = "warehouseId") + open var warehouse: Warehouse? = null + @Column(name = "inQty") open var inQty: BigDecimal? = null - @NotNull @Column(name = "outQty") open var outQty: BigDecimal? = null - @NotNull @Column(name = "holdQty") open var holdQty: BigDecimal? = null - @NotNull @Column(name = "status") open var status: String? = null - @JdbcTypeCode(SqlTypes.JSON) - @Column(name = "qrCode") - open var qrCode: MutableMap? = null + @Column(name = "remarks") + open var remarks: String? = null + +// @JdbcTypeCode(SqlTypes.JSON) +// @Column(name = "qrCode") +// open var qrCode: MutableMap? = null } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLine.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLine.kt index 6e9bc88..d93f1dc 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLine.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLine.kt @@ -64,6 +64,10 @@ open class StockInLine : BaseEntity() { @JoinColumn(name = "userId") open var user: User? = null + @OneToOne + @JoinColumn(name = "inventoryLotId") + open var inventoryLot: InventoryLot? = null + @Column(name = "lotNo") open var lotNo: String? = null diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLineRepository.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLineRepository.kt index 5a3ee06..0fef12f 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLineRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLineRepository.kt @@ -11,5 +11,4 @@ interface StockInLineRepository : AbstractRepository { fun findAllStockInLineInfoByStockInIdAndDeletedFalse(stockInId: Long): List fun findStockInLineInfoByIdAndDeletedFalse(id: Long): StockInLineInfo fun findStockInLineInfoByIdInAndDeletedFalse(id: List): List - fun findQrCodeInfoByIdInAndDeletedFalse(id: List): List } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/QrCodeInfo.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/QrCodeInfo.kt index 94f4dc3..ce1fdbf 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/QrCodeInfo.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/QrCodeInfo.kt @@ -25,5 +25,5 @@ interface QrCodeInfo { // stockInLine val lotNo: String? @get:Value("#{target.stockIn?.supplier?.name}") val supplier: String? - var qrCode: BufferedImage? +// var qrCode: BufferedImage? } diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt index 6516548..5d9b6ea 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/StockInLineInfo.kt @@ -28,4 +28,12 @@ interface StockInLineInfo { val status: String var lotNo: String? var productLotNo: String? + @get:Value("#{target.stockIn?.supplier?.name}") + val supplier: String? + @get:Value("#{target.purchaseOrderLine?.uom?.code}") + val uom: String? + @get:Value("#{target.stockIn?.purchaseOrder?.code}") + val poCode: String + @get:Value("#{target.item?.type}") + val itemType: String } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt index 06d63d3..cf17d24 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt @@ -25,6 +25,7 @@ import java.math.BigDecimal import java.time.LocalDate import java.time.LocalDateTime import com.ffii.core.utils.PdfUtils; +import com.ffii.fpsms.modules.master.entity.WarehouseRepository import java.io.FileNotFoundException import java.time.format.DateTimeFormatter @@ -39,8 +40,9 @@ open class StockInLineService( private val stockInRepository: StockInRepository, private val stockInLineRepository: StockInLineRepository, private val inventoryLotRepository: InventoryLotRepository, + private val inventoryLotLineRepository: InventoryLotLineRepository, private val itemRepository: ItemsRepository, - private val inventoryLotService: InventoryLotService, + private val warehouseRepository: WarehouseRepository, ): AbstractBaseEntityService(jdbcDao, stockInLineRepository) { @Throws(IOException::class) @@ -93,6 +95,20 @@ open class StockInLineService( val savedInventoryLot = inventoryLotRepository.saveAndFlush(inventoryLot) return savedInventoryLot } + @Throws(IOException::class) + @Transactional + fun saveInventoryLotLineWhenStockIn(request: SaveStockInLineRequest, stockInLine: StockInLine): InventoryLotLine { + val inventoryLotLine = InventoryLotLine() + val warehouse = warehouseRepository.findById(request.warehouseId!!).orElseThrow() + inventoryLotLine.apply { + this.inventoryLot = stockInLine.inventoryLot + this.warehouse = warehouse + this.inQty = request.acceptedQty + this.status = "available" + } + val savedInventoryLotLine = inventoryLotLineRepository.saveAndFlush(inventoryLotLine) + return savedInventoryLotLine + } @Throws(IOException::class) @Transactional @@ -134,29 +150,24 @@ open class StockInLineService( // return list of stock in line, update data grid with the list if (request.acceptedQty.compareTo(stockInLine.acceptedQty) == 0) { var savedInventoryLot: InventoryLot? = null + var savedInventoryLotLine: InventoryLotLine? = null // maybe remove this later saveQcResultWhenStockIn(request, stockInLine) - if (request.status == StockInLineStatus.COMPLETE.status) { -// if (request.expiryDate == null) { -// return MessageResponse( -// id = null, -// code = null, -// name = null, -// type = "Found Null", -// message = "missing expiry", -// errorPosition = "expiryDate", -// ) -// } + if (request.status == StockInLineStatus.RECEIVED.status) { savedInventoryLot = saveInventoryLotWhenStockIn(request = request, stockInLine = stockInLine) - println(savedInventoryLot) + } + if (request.status == StockInLineStatus.COMPLETE.status) { + savedInventoryLotLine = saveInventoryLotLineWhenStockIn(request = request, stockInLine = stockInLine) } stockInLine.apply { // user = null - productionDate = request.productionDate?.atStartOfDay() // maybe need to change the request to LocalDateTime - productLotNo = request.productLotNo - receiptDate = request.receiptDate?.atStartOfDay() - status = request.status - expiryDate = stockInLine.expiryDate ?: request.expiryDate - lotNo = savedInventoryLot?.lotNo + this.productionDate = request.productionDate?.atStartOfDay() // maybe need to change the request to LocalDateTime + this.productLotNo = request.productLotNo + this.receiptDate = request.receiptDate?.atStartOfDay() + this.status = request.status + this.expiryDate = stockInLine.expiryDate ?: request.expiryDate + this.inventoryLot = stockInLine.inventoryLot ?: savedInventoryLot + this.lotNo = stockInLine.lotNo ?: savedInventoryLot?.lotNo + this.lotNo = savedInventoryLot?.lotNo } val savedStockInLine = saveAndFlush(stockInLine) val lineInfo = stockInLineRepository.findStockInLineInfoByIdAndDeletedFalse(savedStockInLine.id!!) @@ -183,42 +194,38 @@ open class StockInLineService( val newStockInLine = StockInLine() newStockInLine.apply { this.item = stockInLine.item - itemNo = stockInLine.itemNo + this.itemNo = stockInLine.itemNo this.purchaseOrderLine = stockInLine.purchaseOrderLine this.stockIn = stockInLine.stockIn - demandQty = stockInLine.demandQty - acceptedQty = stockInLine.acceptedQty!!.minus(request.acceptedQty) - price = stockInLine.price - priceUnit = stockInLine.priceUnit - productionDate = stockInLine.productionDate - expiryDate = stockInLine.expiryDate - status = stockInLine.status // this does update status - user = stockInLine.user + this.demandQty = stockInLine.demandQty + this.acceptedQty = stockInLine.acceptedQty!!.minus(request.acceptedQty) + this.price = stockInLine.price + this.priceUnit = stockInLine.priceUnit + this.inventoryLot = stockInLine.inventoryLot + this.lotNo = stockInLine.lotNo + this.productionDate = stockInLine.productionDate + this.expiryDate = stockInLine.expiryDate + this.status = stockInLine.status // this does update status + this.user = stockInLine.user } saveQcResultWhenStockIn(request, stockInLine) var savedInventoryLot: InventoryLot? = null - if (request.status == StockInLineStatus.COMPLETE.status) { -// if (request.expiryDate == null) { -// return MessageResponse( -// id = null, -// code = null, -// name = null, -// type = "Found Null", -// message = "missing expiry", -// errorPosition = "expiryDate", -// ) -// } + var savedInventoryLotLine: InventoryLotLine? = null // maybe remove this later + if (request.status == StockInLineStatus.RECEIVED.status) { savedInventoryLot = saveInventoryLotWhenStockIn(request = request, stockInLine = stockInLine) - println(savedInventoryLot) + } + if (request.status == StockInLineStatus.COMPLETE.status) { + savedInventoryLotLine = saveInventoryLotLineWhenStockIn(request = request, stockInLine = stockInLine) } stockInLine.apply { - receiptDate = request.receiptDate?.atStartOfDay() - productionDate = request.productionDate?.atStartOfDay() - acceptedQty = request.acceptedQty - status = request.status - lotNo = savedInventoryLot?.lotNo - expiryDate = stockInLine.expiryDate ?: request.expiryDate - productLotNo = request.productLotNo + this.receiptDate = request.receiptDate?.atStartOfDay() + this.productionDate = request.productionDate?.atStartOfDay() + this.acceptedQty = request.acceptedQty + this.status = request.status + this.inventoryLot = savedInventoryLot ?: stockInLine.inventoryLot + this.lotNo = savedInventoryLot?.lotNo ?: stockInLine.lotNo + this.expiryDate = stockInLine.expiryDate ?: request.expiryDate + this.productLotNo = request.productLotNo } val stockInLineEntries = listOf(stockInLine, newStockInLine) @@ -249,8 +256,7 @@ open class StockInLineService( } val inputStream = resource.inputStream val poLabel = JasperCompileManager.compileReport(inputStream) - val qrCodeInfo = stockInLineRepository.findQrCodeInfoByIdInAndDeletedFalse(request.stockInLineIds).toMutableList() - println(qrCodeInfo) + val qrCodeInfo = stockInLineRepository.findStockInLineInfoByIdInAndDeletedFalse(request.stockInLineIds).toMutableList() val fields = mutableListOf>() for (info in qrCodeInfo) { val field = mutableMapOf() @@ -259,7 +265,7 @@ open class StockInLineService( ",stockInLineId:${info.id}" ) // field["itemId"] = info.itemId - field["itemName"] = info.itemName + field["itemName"] = info.itemName!! field["itemNo"] = info.itemNo field["poCode"] = info.poCode field["itemType"] = info.itemType diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/StockInLineController.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/StockInLineController.kt index 1c68ec7..2d4980f 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/web/StockInLineController.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/web/StockInLineController.kt @@ -41,9 +41,7 @@ class StockInLineController( val out: OutputStream = response.outputStream val pdf: Map = stockInLineService.exportStockInLineQrcode(request) val jasperPrint = pdf["report"] as JasperPrint - println(pdf["fileName"]) response.addHeader("filename", "${pdf["fileName"]}.pdf") -// response.setHeader("Content-Disposition", "attachment; filename=" + pdf["fileName"] + ".pdf"); out.write(JasperExportManager.exportReportToPdf(jasperPrint)); } diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SaveStockInRequest.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SaveStockInRequest.kt index aba9a99..cafcbda 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SaveStockInRequest.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SaveStockInRequest.kt @@ -46,5 +46,6 @@ data class SaveStockInLineRequest( var productLotNo: String?, var receiptDate: LocalDate?, var productionDate: LocalDate?, - var qcResult: List? + var qcResult: List?, + var warehouseId: Long? ) diff --git a/src/main/resources/db/changelog/changes/20250523_01_derek/01_recreate_inventory_lot_line.sql b/src/main/resources/db/changelog/changes/20250523_01_derek/01_recreate_inventory_lot_line.sql new file mode 100644 index 0000000..71a3254 --- /dev/null +++ b/src/main/resources/db/changelog/changes/20250523_01_derek/01_recreate_inventory_lot_line.sql @@ -0,0 +1,24 @@ +--liquibase formatted sql + +--changeset derek:re create inventory lot line +DROP TABLE `inventory_lot_line`; +CREATE TABLE `inventory_lot_line` +( + `id` INT NOT NULL AUTO_INCREMENT, + `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` VARCHAR(30) NULL DEFAULT NULL, + `version` INT NOT NULL DEFAULT '0', + `modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `modifiedBy` VARCHAR(30) NULL DEFAULT NULL, + `deleted` TINYINT(1) NOT NULL DEFAULT '0', + `inventoryLotId` INT NOT NULL, + `warehouseId` INT NOT NULL, + `inQty` DECIMAL(14, 2) NULL DEFAULT '0', + `outQty` DECIMAL(14, 2) NULL DEFAULT '0', + `holdQty` DECIMAL(14, 2) NULL DEFAULT '0', + `status` VARCHAR(255) NOT NULL, + `remarks` VARCHAR(255) NOT NULL, + CONSTRAINT PK_INVENTORY_LOT_LINE PRIMARY KEY (id), + CONSTRAINT FK_INVENTORY_LOT_LINE_TO_INVENTORY_LOT_ON_INVENTORY_LOT_ID FOREIGN KEY (`inventoryLotId`) REFERENCES `inventory_Lot` (`id`), + CONSTRAINT FK_INVENTORY_LOT_LINE_TO_WAREHOUSE_ON_WAREHOUSE_ID FOREIGN KEY (`warehouseId`) REFERENCES `warehouse` (`id`) +); \ No newline at end of file diff --git a/src/main/resources/db/changelog/changes/20250523_01_derek/02_remake_inv_lot_line_again.sql b/src/main/resources/db/changelog/changes/20250523_01_derek/02_remake_inv_lot_line_again.sql new file mode 100644 index 0000000..fee3fd5 --- /dev/null +++ b/src/main/resources/db/changelog/changes/20250523_01_derek/02_remake_inv_lot_line_again.sql @@ -0,0 +1,24 @@ +--liquibase formatted sql + +--changeset derek:2nd re create inv lot line +DROP TABLE `inventory_lot_line`; +CREATE TABLE `inventory_lot_line` +( + `id` INT NOT NULL AUTO_INCREMENT, + `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `createdBy` VARCHAR(30) NULL DEFAULT NULL, + `version` INT NOT NULL DEFAULT '0', + `modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `modifiedBy` VARCHAR(30) NULL DEFAULT NULL, + `deleted` TINYINT(1) NOT NULL DEFAULT '0', + `inventoryLotId` INT NOT NULL, + `warehouseId` INT NOT NULL, + `inQty` DECIMAL(14, 2) NULL DEFAULT '0', + `outQty` DECIMAL(14, 2) NULL DEFAULT '0', + `holdQty` DECIMAL(14, 2) NULL DEFAULT '0', + `status` VARCHAR(255) NOT NULL DEFAULT 'available', + `remarks` VARCHAR(255) NULL, + CONSTRAINT PK_INVENTORY_LOT_LINE PRIMARY KEY (id), + CONSTRAINT FK_INVENTORY_LOT_LINE_TO_INVENTORY_LOT_ON_INVENTORY_LOT_ID FOREIGN KEY (`inventoryLotId`) REFERENCES `inventory_Lot` (`id`), + CONSTRAINT FK_INVENTORY_LOT_LINE_TO_WAREHOUSE_ON_WAREHOUSE_ID FOREIGN KEY (`warehouseId`) REFERENCES `warehouse` (`id`) +); \ No newline at end of file diff --git a/src/main/resources/db/changelog/changes/20250523_01_derek/03_update_stock_in_line_with_inventoryLotId.sql b/src/main/resources/db/changelog/changes/20250523_01_derek/03_update_stock_in_line_with_inventoryLotId.sql new file mode 100644 index 0000000..441e836 --- /dev/null +++ b/src/main/resources/db/changelog/changes/20250523_01_derek/03_update_stock_in_line_with_inventoryLotId.sql @@ -0,0 +1,5 @@ +--liquibase formatted sql + +--changeset derek:update stock in line with inventory lot id +ALTER TABLE `stock_in_line` +ADD COLUMN `inventoryLotId` INT NULL AFTER `userId`; \ No newline at end of file diff --git a/src/main/resources/db/changelog/changes/20250523_01_derek/04_set_default_lot_line.sql b/src/main/resources/db/changelog/changes/20250523_01_derek/04_set_default_lot_line.sql new file mode 100644 index 0000000..95d710d --- /dev/null +++ b/src/main/resources/db/changelog/changes/20250523_01_derek/04_set_default_lot_line.sql @@ -0,0 +1,7 @@ +--liquibase formatted sql + +--changeset derek:update qty with default value in lot line +ALTER TABLE `inventory_lot_line` +MODIFY COLUMN `inQty` DECIMAL(14, 2) NULL DEFAULT 0, +MODIFY COLUMN `outQty` DECIMAL(14, 2) NULL DEFAULT 0, +MODIFY COLUMN `holdQty` DECIMAL(14, 2) NULL DEFAULT 0; \ No newline at end of file