diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/ItemCategory.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/ItemCategory.kt index e1c26c1..eaee54a 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/ItemCategory.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/ItemCategory.kt @@ -8,8 +8,23 @@ import jakarta.validation.constraints.Size @Entity @Table(name = "item_category") open class ItemCategory : BaseEntity() { - @Size(max = 50) - @NotNull - @Column(name = "name", nullable = false, length = 50) - open var name: String? = null + @Size(max = 100) + @Column(name = "code", length = 100) + open var code: String? = null + + @Size(max = 100) + @Column(name = "parent", length = 100) + open var parent: String? = null + + @Size(max = 100) + @Column(name = "sub", length = 100) + open var sub: String? = null + + @Size(max = 100) + @Column(name = "temperature", length = 100) + open var temperature: String? = null + + @ManyToOne + @JoinColumn(name = "qcCategoryId") + open var qcCategory: QcCategory? = null } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/Items.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/Items.kt index 7d1df01..95e9bcd 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/Items.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/Items.kt @@ -54,4 +54,12 @@ open class Items : BaseEntity() { @JsonManagedReference @OneToOne(mappedBy = "item", cascade = [CascadeType.ALL], orphanRemoval = true) open var bom: Bom? = null + + @ManyToOne + @JoinColumn(name = "categoryId") + open var category: ItemCategory? = null + + @ManyToOne + @JoinColumn(name = "qcCategoryId") + open var qcCategory: QcCategory? = null } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/QcCategory.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/QcCategory.kt index f1b1b3e..be45bc1 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/QcCategory.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/QcCategory.kt @@ -1,5 +1,6 @@ package com.ffii.fpsms.modules.master.entity +import com.fasterxml.jackson.annotation.JsonManagedReference import com.ffii.core.entity.BaseEntity import jakarta.persistence.CascadeType import jakarta.persistence.Column @@ -21,11 +22,15 @@ open class QcCategory : BaseEntity() { @Column(name = "name") open var name: String? = null - @OneToMany(cascade = [CascadeType.ALL]) - @JoinTable( - name = "qc_item_category", - joinColumns = [JoinColumn(name = "qcCategoryId")], - inverseJoinColumns = [JoinColumn(name = "qcItemId")] - ) - open var qcItems: MutableSet = mutableSetOf() +// @OneToMany(cascade = [CascadeType.ALL]) +// @JoinTable( +// name = "qc_item_category", +// joinColumns = [JoinColumn(name = "qcCategoryId")], +// inverseJoinColumns = [JoinColumn(name = "qcItemId")] +// ) +// open var qcItems: MutableList = mutableListOf() + + @JsonManagedReference + @OneToMany(mappedBy = "qcCategory", cascade = [CascadeType.ALL], orphanRemoval = true) + open var qcItemCategory: MutableList = mutableListOf() } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/QcItemCategory.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/QcItemCategory.kt index 00ab0de..8145eb1 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/QcItemCategory.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/QcItemCategory.kt @@ -4,15 +4,14 @@ import com.fasterxml.jackson.annotation.JsonBackReference import com.fasterxml.jackson.annotation.JsonManagedReference import com.ffii.core.entity.BaseEntity import com.ffii.core.entity.IdEntity -import jakarta.persistence.Entity -import jakarta.persistence.JoinColumn -import jakarta.persistence.ManyToOne -import jakarta.persistence.Table +import jakarta.persistence.* import jakarta.validation.constraints.NotNull +import jakarta.validation.constraints.Size @Entity @Table(name = "qc_item_category") open class QcItemCategory : IdEntity() { + @JsonBackReference @NotNull @ManyToOne @JoinColumn(name = "qcCategoryId") @@ -22,4 +21,8 @@ open class QcItemCategory : IdEntity() { @ManyToOne @JoinColumn(name = "qcItemId") open var qcItem: QcItem? = null + + @Size(max = 1000) + @Column(name = "description", length = 1000) + open var description: String? = null } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/ShopRepository.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/ShopRepository.kt index da21491..98f9a63 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/entity/ShopRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/ShopRepository.kt @@ -1,7 +1,7 @@ package com.ffii.fpsms.modules.master.entity import com.ffii.core.support.AbstractRepository -import com.ffii.fpsms.modules.master.entity.projections.SearchId +import com.ffii.fpsms.modules.master.entity.projections.ShopCombo import com.ffii.fpsms.modules.master.enums.ShopType import org.springframework.data.jpa.repository.Query import org.springframework.stereotype.Repository @@ -23,4 +23,6 @@ interface ShopRepository : AbstractRepository { nativeQuery = true, value = "select s.m18Id from Shop s where s.code not regexp ?1 and s.type = ?2 and s.deleted = false") fun findM18IdsByCodeNotRegexpAndTypeAndDeletedIsFalse(codeNotRegexp: String, type: String): List? + + fun findShopComboByTypeAndDeletedIsFalse(type: ShopType): List } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/master/entity/projections/ShopCombo.kt b/src/main/java/com/ffii/fpsms/modules/master/entity/projections/ShopCombo.kt new file mode 100644 index 0000000..7024e59 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/master/entity/projections/ShopCombo.kt @@ -0,0 +1,11 @@ +package com.ffii.fpsms.modules.master.entity.projections + +import org.springframework.beans.factory.annotation.Value + +interface ShopCombo { + val id: Long; + @get:Value("#{target.id}") + val value: Long; + @get:Value("#{target.code} - #{target.name}") + val label: String; +} \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/master/service/ShopService.kt b/src/main/java/com/ffii/fpsms/modules/master/service/ShopService.kt index 40d2d3c..fd3d1aa 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/service/ShopService.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/service/ShopService.kt @@ -2,7 +2,7 @@ package com.ffii.fpsms.modules.master.service import com.ffii.fpsms.modules.master.entity.Shop import com.ffii.fpsms.modules.master.entity.ShopRepository -import com.ffii.fpsms.modules.master.entity.projections.SearchId +import com.ffii.fpsms.modules.master.entity.projections.ShopCombo import com.ffii.fpsms.modules.master.enums.ShopType import com.ffii.fpsms.modules.master.web.models.SaveShopRequest import com.ffii.fpsms.modules.master.web.models.SaveShopResponse @@ -39,6 +39,14 @@ open class ShopService( return shopRepository.findM18IdsByCodeNotRegexpAndTypeAndDeletedIsFalse(codeRegexp, type = ShopType.SUPPLIER.value) } + open fun findSupplierCombo(): List { + return shopRepository.findShopComboByTypeAndDeletedIsFalse(ShopType.SUPPLIER) + } + + open fun findShopCombo(): List { + return shopRepository.findShopComboByTypeAndDeletedIsFalse(ShopType.SHOP) + } + open fun saveShop(request: SaveShopRequest): SaveShopResponse { val shop = if (request.m18Id != null) { when (request.type){ diff --git a/src/main/java/com/ffii/fpsms/modules/master/web/ShopController.kt b/src/main/java/com/ffii/fpsms/modules/master/web/ShopController.kt new file mode 100644 index 0000000..7532eb1 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/master/web/ShopController.kt @@ -0,0 +1,23 @@ +package com.ffii.fpsms.modules.master.web + +import com.ffii.fpsms.modules.master.entity.projections.ShopCombo +import com.ffii.fpsms.modules.master.service.ShopService +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/shop") +class ShopController ( + private val shopService: ShopService, +) { + @GetMapping("/combo/shop") + fun getShopCombo(): List { + return shopService.findShopCombo(); + } + + @GetMapping("/combo/supplier") + fun getSupplierCombo(): List { + return shopService.findSupplierCombo(); + } +} \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/purchaseOrder/entity/projections/PurchaseOrderLineInfo.kt b/src/main/java/com/ffii/fpsms/modules/purchaseOrder/entity/projections/PurchaseOrderLineInfo.kt index 0ae2f54..62e132e 100644 --- a/src/main/java/com/ffii/fpsms/modules/purchaseOrder/entity/projections/PurchaseOrderLineInfo.kt +++ b/src/main/java/com/ffii/fpsms/modules/purchaseOrder/entity/projections/PurchaseOrderLineInfo.kt @@ -1,5 +1,6 @@ package com.ffii.fpsms.modules.purchaseOrder.entity.projections +import com.ffii.fpsms.modules.master.entity.QcItem import com.ffii.fpsms.modules.master.entity.UomConversion import com.ffii.fpsms.modules.stock.entity.StockInLine import com.ffii.fpsms.modules.stock.entity.projection.StockInLineInfo @@ -33,5 +34,14 @@ data class PoLineWithStockInLine ( val price: BigDecimal, val status: String, - val stockInLine: List? + val stockInLine: List?, + + val qcItems: List +) + +data class QcForPoLine ( + val id: Long?, + val code: String?, + val name: String?, + val description: String?, ) \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt b/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt index 0d851a2..4ad02a3 100644 --- a/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt @@ -7,6 +7,7 @@ import com.ffii.fpsms.m18.entity.GrnSendLog import com.ffii.fpsms.m18.entity.GrnSendLogRepository import com.ffii.fpsms.m18.entity.M18DataLogRepository import com.ffii.fpsms.m18.utils.CommonUtils +import com.ffii.fpsms.modules.master.entity.QcItem import com.ffii.fpsms.modules.master.entity.ShopRepository import com.ffii.fpsms.modules.master.service.CurrencyService import com.ffii.fpsms.modules.master.service.ShopService @@ -17,6 +18,7 @@ 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.PurchaseOrderDataClass import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PurchaseOrderInfo +import com.ffii.fpsms.modules.purchaseOrder.entity.projections.QcForPoLine import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderLineStatus import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType @@ -183,18 +185,27 @@ open class PurchaseOrderService( } val mappedPoLine = pol.map { thisPol -> val inLine = stockInLine.filter { it.purchaseOrderLineId == thisPol.id } + val qcItems = thisPol.item?.qcCategory?.qcItemCategory?.map { + QcForPoLine( + id = it.qcItem?.id, + code = it.qcItem?.code, + name = it.qcItem?.name, + description = it.description + ) + } ?: mutableListOf(); PoLineWithStockInLine( - thisPol.id!!, - thisPol.purchaseOrder!!.id!!, - thisPol.item!!.id!!, - thisPol.itemNo!!, - thisPol.item!!.name, - thisPol.qty!!, - inLine.filter{ it.status == StockInLineStatus.COMPLETE.status}.sumOf { it.acceptedQty }, - thisPol.uom!!, - thisPol.price!!, - thisPol.status!!.toString(), - inLine + id = thisPol.id!!, + purchaseOrderId = thisPol.purchaseOrder!!.id!!, + itemId = thisPol.item!!.id!!, + itemNo = thisPol.itemNo!!, + itemName = thisPol.item!!.name, + qty = thisPol.qty!!, + processed = inLine.filter{ it.status == StockInLineStatus.COMPLETE.status}.sumOf { it.acceptedQty }, + uom = thisPol.uom!!, + price = thisPol.price!!, + status = thisPol.status!!.toString(), + stockInLine = inLine, + qcItems = qcItems ) } val result = mapOf( diff --git a/src/main/resources/db/changelog/changes/20250813_01_cyril/01_update_qc.sql b/src/main/resources/db/changelog/changes/20250813_01_cyril/01_update_qc.sql new file mode 100644 index 0000000..447cef1 --- /dev/null +++ b/src/main/resources/db/changelog/changes/20250813_01_cyril/01_update_qc.sql @@ -0,0 +1,20 @@ +-- liquibase formatted sql +-- changeset cyril:update_qc + +ALTER TABLE `qc_item_category` + ADD COLUMN `description` VARCHAR(1000) NULL AFTER `qcCategoryId`; + +ALTER TABLE `item_category` + ADD COLUMN `code` VARCHAR(100) NULL AFTER `deleted`, + ADD COLUMN `sub` VARCHAR(100) NULL AFTER `parent`, + ADD COLUMN `temperature` VARCHAR(100) NULL AFTER `sub`, + ADD COLUMN `qcCategoryId` INT NULL AFTER `temperature`, + CHANGE COLUMN `name` `parent` VARCHAR(100) NULL , + ADD INDEX `FK_ITEM_CATEGORY_ON_QC_CATEGORY_ID` (`qcCategoryId` ASC) VISIBLE; +; +ALTER TABLE `item_category` + ADD CONSTRAINT `FK_ITEM_CATEGORY_ON_QC_CATEGORY_ID` + FOREIGN KEY (`qcCategoryId`) + REFERENCES `qc_category` (`id`) + ON DELETE RESTRICT + ON UPDATE RESTRICT; diff --git a/src/main/resources/db/changelog/changes/20250813_01_cyril/02_add_item_category.sql b/src/main/resources/db/changelog/changes/20250813_01_cyril/02_add_item_category.sql new file mode 100644 index 0000000..d52494d --- /dev/null +++ b/src/main/resources/db/changelog/changes/20250813_01_cyril/02_add_item_category.sql @@ -0,0 +1,13 @@ +-- liquibase formatted sql +-- changeset cyril:add_item_category + +ALTER TABLE `items` + ADD COLUMN `categoryId` INT NULL AFTER `type`, + ADD INDEX `FK_ITEM_ON_CATEGORYID` (`categoryId` ASC) VISIBLE; +; +ALTER TABLE `items` + ADD CONSTRAINT `FK_ITEM_ON_CATEGORYID` + FOREIGN KEY (`categoryId`) + REFERENCES `item_category` (`id`) + ON DELETE RESTRICT + ON UPDATE RESTRICT; diff --git a/src/main/resources/db/changelog/changes/20250813_01_cyril/03_update_qc_item.sql b/src/main/resources/db/changelog/changes/20250813_01_cyril/03_update_qc_item.sql new file mode 100644 index 0000000..c5fc6c0 --- /dev/null +++ b/src/main/resources/db/changelog/changes/20250813_01_cyril/03_update_qc_item.sql @@ -0,0 +1,6 @@ +-- liquibase formatted sql +-- changeset cyril:update_qc_item + +ALTER TABLE `qc_item` + CHANGE COLUMN `code` `code` VARCHAR(100) NOT NULL , + CHANGE COLUMN `name` `name` VARCHAR(100) NOT NULL ; diff --git a/src/main/resources/db/changelog/changes/20250813_01_cyril/04_update_item.sql b/src/main/resources/db/changelog/changes/20250813_01_cyril/04_update_item.sql new file mode 100644 index 0000000..7801ff0 --- /dev/null +++ b/src/main/resources/db/changelog/changes/20250813_01_cyril/04_update_item.sql @@ -0,0 +1,13 @@ +-- liquibase formatted sql +-- changeset cyril:update_item + +ALTER TABLE `items` + ADD COLUMN `qcCategoryId` INT NULL AFTER `categoryId`, + ADD INDEX `FK_ITEM_ON_QCCATEGORYID` (`qcCategoryId` ASC) VISIBLE; +; +ALTER TABLE `items` + ADD CONSTRAINT `FK_ITEM_ON_QCCATEGORYID` + FOREIGN KEY (`qcCategoryId`) + REFERENCES `qc_category` (`id`) + ON DELETE RESTRICT + ON UPDATE RESTRICT; \ No newline at end of file diff --git a/src/main/resources/db/changelog/changes/20250813_01_cyril/05_update_qc_id_with_auto.sql b/src/main/resources/db/changelog/changes/20250813_01_cyril/05_update_qc_id_with_auto.sql new file mode 100644 index 0000000..b67bebe --- /dev/null +++ b/src/main/resources/db/changelog/changes/20250813_01_cyril/05_update_qc_id_with_auto.sql @@ -0,0 +1,41 @@ +-- liquibase formatted sql +-- changeset cyril:update_qc_id_with_auto + +ALTER TABLE `item_category` + DROP FOREIGN KEY `FK_ITEM_CATEGORY_ON_QC_CATEGORY_ID`; + +ALTER TABLE `qc_item_category` + DROP FOREIGN KEY `FK_QC_ITEM_CATEGORY_ON_QCCATEGORYID`; +ALTER TABLE `qc_item_category` + CHANGE COLUMN `id` `id` INT NOT NULL AUTO_INCREMENT , + ADD INDEX `FK_QC_ITEM_CATEGORY_ON_QCCATEGORYID` (`qcCategoryId` ASC) VISIBLE, + DROP INDEX `FK_QC_ITEM_CATEGORY_ON_QCCATEGORYID` ; + +ALTER TABLE `items` + DROP FOREIGN KEY `FK_ITEM_ON_QCCATEGORYID`; + +ALTER TABLE `qc_category` + CHANGE COLUMN `id` `id` INT NOT NULL AUTO_INCREMENT ; + +ALTER TABLE `item_category` ALTER INDEX `FK_ITEM_CATEGORY_ON_QC_CATEGORY_ID` VISIBLE; +ALTER TABLE `item_category` + ADD CONSTRAINT `FK_ITEM_CATEGORY_ON_QC_CATEGORY_ID` + FOREIGN KEY (`qcCategoryId`) + REFERENCES `qc_category` (`id`) + ON DELETE RESTRICT + ON UPDATE RESTRICT; + +ALTER TABLE `qc_item_category` + ADD CONSTRAINT `FK_QC_ITEM_CATEGORY_ON_QCCATEGORYID` + FOREIGN KEY (`qcCategoryId`) + REFERENCES `qc_category` (`id`) + ON DELETE RESTRICT + ON UPDATE RESTRICT; + +ALTER TABLE `items` ALTER INDEX `FK_ITEM_ON_QCCATEGORYID` VISIBLE; +ALTER TABLE `items` + ADD CONSTRAINT `FK_ITEM_ON_QCCATEGORYID` + FOREIGN KEY (`qcCategoryId`) + REFERENCES `qc_category` (`id`) + ON DELETE RESTRICT + ON UPDATE RESTRICT; \ No newline at end of file