| @@ -8,8 +8,23 @@ import jakarta.validation.constraints.Size | |||||
| @Entity | @Entity | ||||
| @Table(name = "item_category") | @Table(name = "item_category") | ||||
| open class ItemCategory : BaseEntity<Long>() { | open class ItemCategory : BaseEntity<Long>() { | ||||
| @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 | |||||
| } | } | ||||
| @@ -54,4 +54,12 @@ open class Items : BaseEntity<Long>() { | |||||
| @JsonManagedReference | @JsonManagedReference | ||||
| @OneToOne(mappedBy = "item", cascade = [CascadeType.ALL], orphanRemoval = true) | @OneToOne(mappedBy = "item", cascade = [CascadeType.ALL], orphanRemoval = true) | ||||
| open var bom: Bom? = null | open var bom: Bom? = null | ||||
| @ManyToOne | |||||
| @JoinColumn(name = "categoryId") | |||||
| open var category: ItemCategory? = null | |||||
| @ManyToOne | |||||
| @JoinColumn(name = "qcCategoryId") | |||||
| open var qcCategory: QcCategory? = null | |||||
| } | } | ||||
| @@ -1,5 +1,6 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | package com.ffii.fpsms.modules.master.entity | ||||
| import com.fasterxml.jackson.annotation.JsonManagedReference | |||||
| import com.ffii.core.entity.BaseEntity | import com.ffii.core.entity.BaseEntity | ||||
| import jakarta.persistence.CascadeType | import jakarta.persistence.CascadeType | ||||
| import jakarta.persistence.Column | import jakarta.persistence.Column | ||||
| @@ -21,11 +22,15 @@ open class QcCategory : BaseEntity<Long>() { | |||||
| @Column(name = "name") | @Column(name = "name") | ||||
| open var name: String? = null | 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<QcItem> = mutableSetOf() | |||||
| // @OneToMany(cascade = [CascadeType.ALL]) | |||||
| // @JoinTable( | |||||
| // name = "qc_item_category", | |||||
| // joinColumns = [JoinColumn(name = "qcCategoryId")], | |||||
| // inverseJoinColumns = [JoinColumn(name = "qcItemId")] | |||||
| // ) | |||||
| // open var qcItems: MutableList<QcItem> = mutableListOf() | |||||
| @JsonManagedReference | |||||
| @OneToMany(mappedBy = "qcCategory", cascade = [CascadeType.ALL], orphanRemoval = true) | |||||
| open var qcItemCategory: MutableList<QcItemCategory> = mutableListOf() | |||||
| } | } | ||||
| @@ -4,15 +4,14 @@ import com.fasterxml.jackson.annotation.JsonBackReference | |||||
| import com.fasterxml.jackson.annotation.JsonManagedReference | import com.fasterxml.jackson.annotation.JsonManagedReference | ||||
| import com.ffii.core.entity.BaseEntity | import com.ffii.core.entity.BaseEntity | ||||
| import com.ffii.core.entity.IdEntity | 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.NotNull | ||||
| import jakarta.validation.constraints.Size | |||||
| @Entity | @Entity | ||||
| @Table(name = "qc_item_category") | @Table(name = "qc_item_category") | ||||
| open class QcItemCategory : IdEntity<Long>() { | open class QcItemCategory : IdEntity<Long>() { | ||||
| @JsonBackReference | |||||
| @NotNull | @NotNull | ||||
| @ManyToOne | @ManyToOne | ||||
| @JoinColumn(name = "qcCategoryId") | @JoinColumn(name = "qcCategoryId") | ||||
| @@ -22,4 +21,8 @@ open class QcItemCategory : IdEntity<Long>() { | |||||
| @ManyToOne | @ManyToOne | ||||
| @JoinColumn(name = "qcItemId") | @JoinColumn(name = "qcItemId") | ||||
| open var qcItem: QcItem? = null | open var qcItem: QcItem? = null | ||||
| @Size(max = 1000) | |||||
| @Column(name = "description", length = 1000) | |||||
| open var description: String? = null | |||||
| } | } | ||||
| @@ -1,7 +1,7 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | package com.ffii.fpsms.modules.master.entity | ||||
| import com.ffii.core.support.AbstractRepository | 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 com.ffii.fpsms.modules.master.enums.ShopType | ||||
| import org.springframework.data.jpa.repository.Query | import org.springframework.data.jpa.repository.Query | ||||
| import org.springframework.stereotype.Repository | import org.springframework.stereotype.Repository | ||||
| @@ -23,4 +23,6 @@ interface ShopRepository : AbstractRepository<Shop, Long> { | |||||
| nativeQuery = true, | nativeQuery = true, | ||||
| value = "select s.m18Id from Shop s where s.code not regexp ?1 and s.type = ?2 and s.deleted = false") | 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<Long>? | fun findM18IdsByCodeNotRegexpAndTypeAndDeletedIsFalse(codeNotRegexp: String, type: String): List<Long>? | ||||
| fun findShopComboByTypeAndDeletedIsFalse(type: ShopType): List<ShopCombo> | |||||
| } | } | ||||
| @@ -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; | |||||
| } | |||||
| @@ -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.Shop | ||||
| import com.ffii.fpsms.modules.master.entity.ShopRepository | 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.enums.ShopType | ||||
| import com.ffii.fpsms.modules.master.web.models.SaveShopRequest | import com.ffii.fpsms.modules.master.web.models.SaveShopRequest | ||||
| import com.ffii.fpsms.modules.master.web.models.SaveShopResponse | import com.ffii.fpsms.modules.master.web.models.SaveShopResponse | ||||
| @@ -39,6 +39,14 @@ open class ShopService( | |||||
| return shopRepository.findM18IdsByCodeNotRegexpAndTypeAndDeletedIsFalse(codeRegexp, type = ShopType.SUPPLIER.value) | return shopRepository.findM18IdsByCodeNotRegexpAndTypeAndDeletedIsFalse(codeRegexp, type = ShopType.SUPPLIER.value) | ||||
| } | } | ||||
| open fun findSupplierCombo(): List<ShopCombo> { | |||||
| return shopRepository.findShopComboByTypeAndDeletedIsFalse(ShopType.SUPPLIER) | |||||
| } | |||||
| open fun findShopCombo(): List<ShopCombo> { | |||||
| return shopRepository.findShopComboByTypeAndDeletedIsFalse(ShopType.SHOP) | |||||
| } | |||||
| open fun saveShop(request: SaveShopRequest): SaveShopResponse { | open fun saveShop(request: SaveShopRequest): SaveShopResponse { | ||||
| val shop = if (request.m18Id != null) { | val shop = if (request.m18Id != null) { | ||||
| when (request.type){ | when (request.type){ | ||||
| @@ -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<ShopCombo> { | |||||
| return shopService.findShopCombo(); | |||||
| } | |||||
| @GetMapping("/combo/supplier") | |||||
| fun getSupplierCombo(): List<ShopCombo> { | |||||
| return shopService.findSupplierCombo(); | |||||
| } | |||||
| } | |||||
| @@ -1,5 +1,6 @@ | |||||
| package com.ffii.fpsms.modules.purchaseOrder.entity.projections | 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.master.entity.UomConversion | ||||
| import com.ffii.fpsms.modules.stock.entity.StockInLine | import com.ffii.fpsms.modules.stock.entity.StockInLine | ||||
| import com.ffii.fpsms.modules.stock.entity.projection.StockInLineInfo | import com.ffii.fpsms.modules.stock.entity.projection.StockInLineInfo | ||||
| @@ -33,5 +34,14 @@ data class PoLineWithStockInLine ( | |||||
| val price: BigDecimal, | val price: BigDecimal, | ||||
| val status: String, | val status: String, | ||||
| val stockInLine: List<StockInLineInfo>? | |||||
| val stockInLine: List<StockInLineInfo>?, | |||||
| val qcItems: List<QcForPoLine> | |||||
| ) | |||||
| data class QcForPoLine ( | |||||
| val id: Long?, | |||||
| val code: String?, | |||||
| val name: String?, | |||||
| val description: String?, | |||||
| ) | ) | ||||
| @@ -7,6 +7,7 @@ import com.ffii.fpsms.m18.entity.GrnSendLog | |||||
| import com.ffii.fpsms.m18.entity.GrnSendLogRepository | import com.ffii.fpsms.m18.entity.GrnSendLogRepository | ||||
| import com.ffii.fpsms.m18.entity.M18DataLogRepository | import com.ffii.fpsms.m18.entity.M18DataLogRepository | ||||
| import com.ffii.fpsms.m18.utils.CommonUtils | 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.entity.ShopRepository | ||||
| import com.ffii.fpsms.modules.master.service.CurrencyService | import com.ffii.fpsms.modules.master.service.CurrencyService | ||||
| import com.ffii.fpsms.modules.master.service.ShopService | 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.PoLineWithStockInLine | ||||
| import com.ffii.fpsms.modules.purchaseOrder.entity.projections.PurchaseOrderDataClass | 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.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.PurchaseOrderLineStatus | ||||
| import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus | import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderStatus | ||||
| import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType | import com.ffii.fpsms.modules.purchaseOrder.enums.PurchaseOrderType | ||||
| @@ -183,18 +185,27 @@ open class PurchaseOrderService( | |||||
| } | } | ||||
| val mappedPoLine = pol.map { thisPol -> | val mappedPoLine = pol.map { thisPol -> | ||||
| val inLine = stockInLine.filter { it.purchaseOrderLineId == thisPol.id } | 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( | 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( | val result = mapOf( | ||||
| @@ -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; | |||||
| @@ -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; | |||||
| @@ -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 ; | |||||
| @@ -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; | |||||
| @@ -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; | |||||