| @@ -0,0 +1,52 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.entity.BaseEntity | |||||
| import jakarta.persistence.* | |||||
| import jakarta.validation.constraints.NotNull | |||||
| import jakarta.validation.constraints.Size | |||||
| import java.math.BigDecimal | |||||
| import java.time.Instant | |||||
| import java.time.LocalDateTime | |||||
| @Table(name = "bom") | |||||
| @Entity | |||||
| open class Bom : BaseEntity<Long>() { | |||||
| @ManyToOne | |||||
| @JoinColumn(name = "itemId") | |||||
| open var item: Items? = null | |||||
| @Size(max = 30) | |||||
| @NotNull | |||||
| @Column(name = "code", nullable = false, length = 30) | |||||
| open var code: String? = null | |||||
| @Size(max = 30) | |||||
| @NotNull | |||||
| @Column(name = "name", nullable = false, length = 30) | |||||
| open var name: String? = null | |||||
| @Size(max = 100) | |||||
| @NotNull | |||||
| @Column(name = "description", nullable = false, length = 100) | |||||
| open var description: String? = null | |||||
| @Column(name = "outputQty", precision = 14, scale = 2) | |||||
| open var outputQty: BigDecimal? = null | |||||
| @Size(max = 50) | |||||
| @Column(name = "outputQtyUom", length = 50) | |||||
| open var outputQtyUom: String? = null | |||||
| @Column(name = "yield", precision = 14, scale = 2) | |||||
| open var yield: BigDecimal? = null | |||||
| @ManyToOne | |||||
| @JoinColumn(name = "uomId") | |||||
| open var uom: UomConversion? = null | |||||
| @Column(name = "m18Id") | |||||
| open var m18Id: Long? = null | |||||
| @Column(name = "m18LastModifyDate") | |||||
| open var m18LastModifyDate: LocalDateTime? = null | |||||
| } | |||||
| @@ -0,0 +1,54 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.entity.BaseEntity | |||||
| import jakarta.persistence.* | |||||
| import jakarta.validation.constraints.NotNull | |||||
| import jakarta.validation.constraints.Size | |||||
| import java.math.BigDecimal | |||||
| import java.time.Instant | |||||
| import java.time.LocalDateTime | |||||
| @Table(name = "bom_material") | |||||
| @Entity | |||||
| open class BomMaterial : BaseEntity<Long>() { | |||||
| @ManyToOne | |||||
| @JoinColumn(name = "itemId") | |||||
| open var item: Items? = null | |||||
| @Size(max = 50) | |||||
| @Column(name = "itemName", length = 50) | |||||
| open var itemName: String? = null | |||||
| @NotNull | |||||
| @Column(name = "isConsumable", nullable = false) | |||||
| open var isConsumable: Boolean? = false | |||||
| @NotNull | |||||
| @Column(name = "qty", nullable = false, precision = 14, scale = 2) | |||||
| open var qty: BigDecimal? = null | |||||
| @ManyToOne | |||||
| @JoinColumn(name = "uomId") | |||||
| open var uom: UomConversion? = null | |||||
| @Size(max = 50) | |||||
| @Column(name = "uomName", length = 50) | |||||
| open var uomName: String? = null | |||||
| @NotNull | |||||
| @ManyToOne(optional = false) | |||||
| @JoinColumn(name = "bomId", nullable = false) | |||||
| open var bom: Bom? = null | |||||
| @NotNull | |||||
| @Column(name = "m18Id", nullable = false) | |||||
| open var m18Id: Long? = null | |||||
| @NotNull | |||||
| @Column(name = "m18LastModifyDate", nullable = false) | |||||
| open var m18LastModifyDate: LocalDateTime? = null | |||||
| @Size(max = 1000) | |||||
| @Column(name = "remarks", length = 1000) | |||||
| open var remarks: String? = null | |||||
| } | |||||
| @@ -0,0 +1,12 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.support.AbstractRepository | |||||
| import org.springframework.stereotype.Repository | |||||
| import java.io.Serializable | |||||
| @Repository | |||||
| interface BomMaterialRepository : AbstractRepository<BomMaterial, Long> { | |||||
| fun findByIdAndDeletedIsFalse(id: Serializable): BomMaterial? | |||||
| fun findByM18IdAndDeletedIsFalse(m18Id: Long): BomMaterial? | |||||
| } | |||||
| @@ -0,0 +1,28 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.entity.BaseEntity | |||||
| import jakarta.persistence.* | |||||
| import jakarta.validation.constraints.NotNull | |||||
| @Table(name = "bom_process") | |||||
| @Entity | |||||
| open class BomProcess : BaseEntity<Long>() { | |||||
| @NotNull | |||||
| @ManyToOne(optional = false) | |||||
| @JoinColumn(name = "processId", nullable = false) | |||||
| open var process: Process? = null | |||||
| @NotNull | |||||
| @ManyToOne(optional = false) | |||||
| @JoinColumn(name = "uomId", nullable = false) | |||||
| open var uom: UomConversion? = null | |||||
| @NotNull | |||||
| @Column(name = "seqNo", nullable = false) | |||||
| open var seqNo: Long? = null | |||||
| @NotNull | |||||
| @ManyToOne(optional = false) | |||||
| @JoinColumn(name = "bomId", nullable = false) | |||||
| open var bom: Bom? = null | |||||
| } | |||||
| @@ -0,0 +1,19 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.entity.BaseEntity | |||||
| import jakarta.persistence.* | |||||
| import jakarta.validation.constraints.NotNull | |||||
| @Table(name = "bom_process_material") | |||||
| @Entity | |||||
| open class BomProcessMaterial : BaseEntity<Long>() { | |||||
| @NotNull | |||||
| @ManyToOne(optional = false) | |||||
| @JoinColumn(name = "bomProcessId", nullable = false) | |||||
| open var bomProcess: BomProcess? = null | |||||
| @NotNull | |||||
| @ManyToOne(optional = false) | |||||
| @JoinColumn(name = "bomMaterialId", nullable = false) | |||||
| open var bomMaterial: BomMaterial? = null | |||||
| } | |||||
| @@ -0,0 +1,8 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.support.AbstractRepository | |||||
| import org.springframework.stereotype.Repository | |||||
| @Repository | |||||
| interface BomProcessMaterialRepository : AbstractRepository<BomProcessMaterial, Long> { | |||||
| } | |||||
| @@ -0,0 +1,8 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.support.AbstractRepository | |||||
| import org.springframework.stereotype.Repository | |||||
| @Repository | |||||
| interface BomProcessRepository : AbstractRepository<BomProcess, Long> { | |||||
| } | |||||
| @@ -0,0 +1,12 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.support.AbstractRepository | |||||
| import org.springframework.stereotype.Repository | |||||
| import java.io.Serializable | |||||
| @Repository | |||||
| interface BomRepository : AbstractRepository<Bom, Long> { | |||||
| fun findByIdAndDeletedIsFalse(id: Serializable): Bom? | |||||
| fun findByM18IdAndDeletedIsFalse(m18Id: Long): Bom? | |||||
| } | |||||
| @@ -0,0 +1,29 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.entity.BaseEntity | |||||
| import jakarta.persistence.* | |||||
| import jakarta.validation.constraints.NotNull | |||||
| import jakarta.validation.constraints.Size | |||||
| @Table(name = "equipment") | |||||
| @Entity | |||||
| open class Equipment : BaseEntity<Long>() { | |||||
| @Size(max = 30) | |||||
| @NotNull | |||||
| @Column(name = "code", nullable = false, length = 30) | |||||
| open var code: String? = null | |||||
| @Size(max = 30) | |||||
| @NotNull | |||||
| @Column(name = "name", nullable = false, length = 30) | |||||
| open var name: String? = null | |||||
| @Size(max = 500) | |||||
| @NotNull | |||||
| @Column(name = "description", nullable = false, length = 500) | |||||
| open var description: String? = null | |||||
| @ManyToOne | |||||
| @JoinColumn(name = "equipmentTypeId") | |||||
| open var equipmentType: EquipmentType? = null | |||||
| } | |||||
| @@ -0,0 +1,8 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.support.AbstractRepository | |||||
| import org.springframework.stereotype.Repository | |||||
| @Repository | |||||
| interface EquipmentRepository : AbstractRepository<Equipment, Long> { | |||||
| } | |||||
| @@ -0,0 +1,27 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.entity.BaseEntity | |||||
| import jakarta.persistence.Column | |||||
| import jakarta.persistence.Entity | |||||
| import jakarta.persistence.Table | |||||
| import jakarta.validation.constraints.NotNull | |||||
| import jakarta.validation.constraints.Size | |||||
| @Table(name = "equipment_type") | |||||
| @Entity | |||||
| open class EquipmentType : BaseEntity<Long>() { | |||||
| @Size(max = 30) | |||||
| @NotNull | |||||
| @Column(name = "code", nullable = false, length = 30) | |||||
| open var code: String? = null | |||||
| @Size(max = 30) | |||||
| @NotNull | |||||
| @Column(name = "name", nullable = false, length = 30) | |||||
| open var name: String? = null | |||||
| @Size(max = 500) | |||||
| @NotNull | |||||
| @Column(name = "description", nullable = false, length = 500) | |||||
| open var description: String? = null | |||||
| } | |||||
| @@ -0,0 +1,8 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.support.AbstractRepository | |||||
| import org.springframework.stereotype.Repository | |||||
| @Repository | |||||
| interface EquipmentTypeRepository : AbstractRepository<EquipmentType, Long> { | |||||
| } | |||||
| @@ -1,5 +1,6 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | package com.ffii.fpsms.modules.master.entity | ||||
| import com.fasterxml.jackson.annotation.JsonBackReference | |||||
| import com.ffii.core.entity.BaseEntity | import com.ffii.core.entity.BaseEntity | ||||
| import jakarta.persistence.* | import jakarta.persistence.* | ||||
| import jakarta.validation.constraints.NotNull | import jakarta.validation.constraints.NotNull | ||||
| @@ -12,11 +13,13 @@ open class ItemUom : BaseEntity<Long>() { | |||||
| @NotNull | @NotNull | ||||
| @ManyToOne | @ManyToOne | ||||
| @JoinColumn(name = "uomId", nullable = false) | @JoinColumn(name = "uomId", nullable = false) | ||||
| @JsonBackReference | |||||
| open var uom: UomConversion? = null | open var uom: UomConversion? = null | ||||
| @NotNull | @NotNull | ||||
| @ManyToOne | @ManyToOne | ||||
| @JoinColumn(name = "itemId", nullable = false) | @JoinColumn(name = "itemId", nullable = false) | ||||
| @JsonBackReference | |||||
| open var item: Items? = null | open var item: Items? = null | ||||
| @NotNull | @NotNull | ||||
| @@ -1,6 +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 org.springframework.data.jpa.repository.Query | |||||
| import org.springframework.stereotype.Repository | import org.springframework.stereotype.Repository | ||||
| import java.io.Serializable | import java.io.Serializable | ||||
| @@ -15,4 +16,6 @@ interface ItemUomRespository : AbstractRepository<ItemUom, Long> { | |||||
| fun deleteAllByIdIn(id: List<Serializable>) | fun deleteAllByIdIn(id: List<Serializable>) | ||||
| fun findByItemIdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom? | fun findByItemIdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemId: Serializable): ItemUom? | ||||
| fun findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemM18Id: Long): ItemUom? | |||||
| } | } | ||||
| @@ -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.* | import jakarta.persistence.* | ||||
| import jakarta.validation.constraints.NotNull | import jakarta.validation.constraints.NotNull | ||||
| @@ -41,6 +42,7 @@ open class Items : BaseEntity<Long>() { | |||||
| @Column(name = "m18LastModifyDate") | @Column(name = "m18LastModifyDate") | ||||
| open var m18LastModifyDate: LocalDateTime? = null | open var m18LastModifyDate: LocalDateTime? = null | ||||
| @JsonManagedReference | |||||
| @OneToMany(mappedBy = "item", cascade = [CascadeType.ALL], orphanRemoval = true) | @OneToMany(mappedBy = "item", cascade = [CascadeType.ALL], orphanRemoval = true) | ||||
| open var itemUoms: MutableSet<ItemUom> = mutableSetOf() | open var itemUoms: MutableSet<ItemUom> = mutableSetOf() | ||||
| } | } | ||||
| @@ -2,15 +2,54 @@ 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.web.models.ItemType | import com.ffii.fpsms.modules.master.web.models.ItemType | ||||
| import org.springframework.data.jpa.repository.Query | |||||
| import org.springframework.stereotype.Repository | import org.springframework.stereotype.Repository | ||||
| import java.io.Serializable | |||||
| @Repository | @Repository | ||||
| interface ItemsRepository : AbstractRepository<Items, Long> { | interface ItemsRepository : AbstractRepository<Items, Long> { | ||||
| fun findAllByDeletedFalse(): List<Items>; | fun findAllByDeletedFalse(): List<Items>; | ||||
| fun findByIdAndDeletedFalse(id: Long): Items; | |||||
| fun findByIdAndDeletedFalse(id: Long): Items?; | |||||
| fun findByCodeAndTypeAndDeletedFalse(code: String, type: String): Items?; | fun findByCodeAndTypeAndDeletedFalse(code: String, type: String): Items?; | ||||
| fun findByM18IdAndDeletedIsFalse(m18Id: Long): Items?; | fun findByM18IdAndDeletedIsFalse(m18Id: Long): Items?; | ||||
| @Query( | |||||
| """ | |||||
| select i from Items i | |||||
| join i.itemUoms iu | |||||
| join iu.uom u | |||||
| where i.name = :name and u.m18Id = :m18UomId and i.deleted = false | |||||
| order by i.id | |||||
| limit 1 | |||||
| """ | |||||
| ) | |||||
| fun findByNameExactlyAndUomM18Id(name: String, m18UomId: Long): Items?; | |||||
| @Query( | |||||
| """ | |||||
| select i from Items i | |||||
| join i.itemUoms iu | |||||
| join iu.uom u | |||||
| where i.name like %:name% and u.m18Id = :m18UomId and i.deleted = false | |||||
| order by i.id | |||||
| limit 1 | |||||
| """ | |||||
| ) | |||||
| fun findByNameLikeAndUomM18Id(name: String, m18UomId: Long): Items?; | |||||
| @Query( | |||||
| nativeQuery = true, | |||||
| value = | |||||
| """ | |||||
| select i.* from items i | |||||
| where :m18BomCode like concat('%',i.code,'%') | |||||
| and i.deleted = false | |||||
| order by i.id | |||||
| limit 1 | |||||
| """ | |||||
| ) | |||||
| fun findByM18BomCode(m18BomCode: String): Items?; | |||||
| } | } | ||||
| @@ -0,0 +1,32 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.entity.BaseEntity | |||||
| import jakarta.persistence.Column | |||||
| import jakarta.persistence.Entity | |||||
| import jakarta.persistence.Table | |||||
| import jakarta.validation.constraints.NotNull | |||||
| import jakarta.validation.constraints.Size | |||||
| @Table(name = "process") | |||||
| @Entity | |||||
| open class Process : BaseEntity<Long>() { | |||||
| @Size(max = 30) | |||||
| @NotNull | |||||
| @Column(name = "code", nullable = false, length = 30) | |||||
| open var code: String? = null | |||||
| @Size(max = 30) | |||||
| @NotNull | |||||
| @Column(name = "name", nullable = false, length = 30) | |||||
| open var name: String? = null | |||||
| @Size(max = 1000) | |||||
| @NotNull | |||||
| @Column(name = "description", nullable = true, length = 1000) | |||||
| open var description: String? = null | |||||
| @Size(max = 1000) | |||||
| @NotNull | |||||
| @Column(name = "remarks", nullable = true, length = 1000) | |||||
| open var remarks: String? = null | |||||
| } | |||||
| @@ -0,0 +1,19 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.entity.BaseEntity | |||||
| import jakarta.persistence.* | |||||
| import jakarta.validation.constraints.NotNull | |||||
| @Table(name = "process_equipment") | |||||
| @Entity | |||||
| open class ProcessEquipment : BaseEntity<Long>() { | |||||
| @NotNull | |||||
| @ManyToOne(optional = false) | |||||
| @JoinColumn(name = "equipmentId", nullable = false) | |||||
| open var equipment: Equipment? = null | |||||
| @NotNull | |||||
| @ManyToOne(optional = false) | |||||
| @JoinColumn(name = "processId", nullable = false) | |||||
| open var process: Process? = null | |||||
| } | |||||
| @@ -0,0 +1,8 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.support.AbstractRepository | |||||
| import org.springframework.stereotype.Repository | |||||
| @Repository | |||||
| interface ProcessEquipmentRepository : AbstractRepository<ProcessEquipment, Long> { | |||||
| } | |||||
| @@ -0,0 +1,8 @@ | |||||
| package com.ffii.fpsms.modules.master.entity | |||||
| import com.ffii.core.support.AbstractRepository | |||||
| import org.springframework.stereotype.Repository | |||||
| @Repository | |||||
| interface ProcessRepository: AbstractRepository<Process, Long> { | |||||
| } | |||||
| @@ -12,15 +12,15 @@ interface ShopRepository : AbstractRepository<Shop, Long> { | |||||
| fun findByIdAndDeletedIsFalse(id: Long): Shop? | fun findByIdAndDeletedIsFalse(id: Long): Shop? | ||||
| fun findByM18IdAndDeletedIsFalse(m18Id: Long): Shop? | |||||
| fun findByM18IdAndTypeAndDeletedIsFalse(m18Id: Long, type: ShopType): Shop? | |||||
| @Query( | @Query( | ||||
| nativeQuery = true, | nativeQuery = true, | ||||
| value = "select s.id from Shop s where s.code regexp ?1 and s.type = ?2 and s.deleted = false") | |||||
| fun findIdsByCodeRegexpAndTypeAndDeletedIsFalse(codeRegexp: String, type: String): List<Long>? | |||||
| value = "select s.m18Id from shop s where s.code regexp ?1 and s.type = ?2 and s.deleted = false") | |||||
| fun findM18IdsByCodeRegexpAndTypeAndDeletedIsFalse(codeRegexp: String, type: String): List<Long>? | |||||
| @Query( | @Query( | ||||
| nativeQuery = true, | nativeQuery = true, | ||||
| value = "select s.id from Shop s where s.code not regexp ?1 and s.type = ?2 and s.deleted = false") | |||||
| fun findIdsByCodeNotRegexpAndTypeAndDeletedIsFalse(codeNotRegexp: String, type: String): List<Long>? | |||||
| 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>? | |||||
| } | } | ||||
| @@ -7,7 +7,7 @@ import java.time.LocalDateTime | |||||
| @Repository | @Repository | ||||
| interface UomConversionRepository : AbstractRepository<UomConversion, Long> { | interface UomConversionRepository : AbstractRepository<UomConversion, Long> { | ||||
| //fun importFromM18(): ArrayList<UomConversion>; | //fun importFromM18(): ArrayList<UomConversion>; | ||||
| fun findByIdAndDeletedFalse(id: Long): UomConversion; | |||||
| fun findByIdAndDeletedFalse(id: Long): UomConversion?; | |||||
| fun findByM18IdAndDeletedFalse(m18Id: Long): UomConversion?; | fun findByM18IdAndDeletedFalse(m18Id: Long): UomConversion?; | ||||
| @@ -0,0 +1,65 @@ | |||||
| package com.ffii.fpsms.modules.master.service | |||||
| import com.ffii.fpsms.modules.master.entity.* | |||||
| import com.ffii.fpsms.modules.master.web.models.SaveBomMaterialRequest | |||||
| import com.ffii.fpsms.modules.master.web.models.SaveBomMaterialResponse | |||||
| import org.springframework.stereotype.Service | |||||
| @Service | |||||
| open class BomMaterialService( | |||||
| val bomMaterialRepository: BomMaterialRepository, | |||||
| val itemsService: ItemsService, | |||||
| val uomConversionService: UomConversionService, | |||||
| val bomService: BomService, | |||||
| ) { | |||||
| open fun findById(id: Long): BomMaterial? { | |||||
| return bomMaterialRepository.findByIdAndDeletedIsFalse(id); | |||||
| } | |||||
| open fun findByM18Id(m18Id: Long): BomMaterial? { | |||||
| return bomMaterialRepository.findByM18IdAndDeletedIsFalse(m18Id); | |||||
| } | |||||
| open fun saveBomMaterial(request: SaveBomMaterialRequest): SaveBomMaterialResponse { | |||||
| val bomMaterial = request.m18Id?.let { findByM18Id(it) } | |||||
| ?: request.id?.let { findById(it) } | |||||
| ?: BomMaterial(); | |||||
| val item = request.m18ItemId?.let { itemsService.findByM18Id(it) } | |||||
| ?: request.itemId?.let { itemsService.findById(it) } | |||||
| val uom = request.m18UomId?.let { uomConversionService.findByM18Id(it) } | |||||
| ?: request.uomId?.let { uomConversionService.findById(it) } | |||||
| val bom = request.m18BomId?.let { bomService.findById(it) } | |||||
| ?: request.bomId?.let { bomService.findById(it) } | |||||
| ?: Bom() | |||||
| bomMaterial.apply { | |||||
| this.item = item | |||||
| itemName = request.itemName | |||||
| isConsumable = request.isConsumable | |||||
| qty = request.qty | |||||
| this.uom = uom | |||||
| uomName = request.uomName | |||||
| this.bom = bom | |||||
| m18Id = request.m18Id ?: m18Id | |||||
| m18LastModifyDate = request.m18LastModifyDate ?: m18LastModifyDate | |||||
| remarks = request.remarks | |||||
| } | |||||
| val response = bomMaterialRepository.saveAndFlush(bomMaterial).let { | |||||
| SaveBomMaterialResponse( | |||||
| id = it.id, | |||||
| itemName = it.itemName, | |||||
| isConsumable = it.isConsumable, | |||||
| qty = it.qty, | |||||
| uomName = it.uomName, | |||||
| bomCode = it.bom?.code, | |||||
| remarks = it.remarks | |||||
| ) | |||||
| } | |||||
| return response | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,64 @@ | |||||
| package com.ffii.fpsms.modules.master.service | |||||
| import com.ffii.fpsms.modules.master.entity.Bom | |||||
| import com.ffii.fpsms.modules.master.entity.BomRepository | |||||
| import com.ffii.fpsms.modules.master.web.models.SaveBomRequest | |||||
| import com.ffii.fpsms.modules.master.web.models.SaveBomResponse | |||||
| import org.springframework.stereotype.Service | |||||
| import kotlin.jvm.optionals.getOrNull | |||||
| @Service | |||||
| open class BomService( | |||||
| val bomRepository: BomRepository, | |||||
| val itemsService: ItemsService, | |||||
| val uomConversionService: UomConversionService | |||||
| ) { | |||||
| open fun findById(id: Long): Bom? { | |||||
| return bomRepository.findByIdAndDeletedIsFalse(id) | |||||
| } | |||||
| open fun findByM18Id(m18Id: Long): Bom? { | |||||
| return bomRepository.findByM18IdAndDeletedIsFalse(m18Id) | |||||
| } | |||||
| open fun saveBom(request: SaveBomRequest): SaveBomResponse { | |||||
| val item = request.code.let { itemsService.findByM18BomCode(it) } ?: request.itemId?.let { itemsService.findById(it) } | |||||
| val uom = request.m18UomId?.let { uomConversionService.findByM18Id(it) } | |||||
| ?: request.uomId?.let { uomConversionService.findById(it) } | |||||
| val bom = request.m18Id?.let { findByM18Id(it) } | |||||
| ?: request.id?.let { findById(it) } | |||||
| ?: Bom() | |||||
| bom.apply { | |||||
| this.item = item | |||||
| code = request.code | |||||
| name = request.name | |||||
| description = request.description | |||||
| outputQty = request.outputQty | |||||
| outputQtyUom = request.outputQtyUom | |||||
| yield = request.yield | |||||
| this.uom = uom | |||||
| m18Id = request.m18Id ?: m18Id | |||||
| m18LastModifyDate = request.m18LastModifyDate ?: m18LastModifyDate | |||||
| } | |||||
| val response = bomRepository.saveAndFlush(bom).let { | |||||
| SaveBomResponse( | |||||
| id = it.id, | |||||
| code = it.code, | |||||
| name = it.name, | |||||
| description = it.description, | |||||
| outputQty = it.outputQty, | |||||
| outputQtyUom = it.outputQtyUom, | |||||
| yield = it.yield, | |||||
| uomName = uom?.udfudesc, | |||||
| ) | |||||
| } | |||||
| return response | |||||
| } | |||||
| } | |||||
| @@ -2,7 +2,7 @@ package com.ffii.fpsms.modules.master.service | |||||
| import com.ffii.fpsms.modules.master.entity.Currency | import com.ffii.fpsms.modules.master.entity.Currency | ||||
| import com.ffii.fpsms.modules.master.entity.CurrencyRepository | import com.ffii.fpsms.modules.master.entity.CurrencyRepository | ||||
| import com.ffii.fpsms.modules.master.web.models.CurrencyRequest | |||||
| import com.ffii.fpsms.modules.master.web.models.SaveCurrencyRequest | |||||
| import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
| @Service | @Service | ||||
| @@ -17,7 +17,7 @@ open class CurrencyService( | |||||
| return currencyRepository.findByM18IdAndDeletedIsFalse(m18Id); | return currencyRepository.findByM18IdAndDeletedIsFalse(m18Id); | ||||
| } | } | ||||
| open fun saveCurrency(request: CurrencyRequest): Currency { | |||||
| open fun saveCurrency(request: SaveCurrencyRequest): Currency { | |||||
| val currency = request.m18Id?.let { findByM18Id(it) } ?: request.id?.let { findById(it) } ?: Currency() | val currency = request.m18Id?.let { findByM18Id(it) } ?: request.id?.let { findById(it) } ?: Currency() | ||||
| currency.apply { | currency.apply { | ||||
| @@ -4,6 +4,8 @@ import com.ffii.fpsms.modules.master.entity.ItemUom | |||||
| import com.ffii.fpsms.modules.master.entity.ItemUomRespository | import com.ffii.fpsms.modules.master.entity.ItemUomRespository | ||||
| import com.ffii.fpsms.modules.master.web.models.ItemUomRequest | import com.ffii.fpsms.modules.master.web.models.ItemUomRequest | ||||
| import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
| import org.springframework.transaction.annotation.Transactional | |||||
| import java.io.IOException | |||||
| import kotlin.jvm.optionals.getOrNull | import kotlin.jvm.optionals.getOrNull | ||||
| @Service | @Service | ||||
| @@ -25,9 +27,21 @@ open class ItemUomService( | |||||
| return itemUomRespository.findByM18IdAndDeletedIsFalse(m18Id); | return itemUomRespository.findByM18IdAndDeletedIsFalse(m18Id); | ||||
| } | } | ||||
| open fun findPurchaseUnitByItemId(itemId: Long): ItemUom? { | |||||
| return itemUomRespository.findByItemIdAndPurchaseUnitIsTrueAndDeletedIsFalse(itemId) | |||||
| } | |||||
| open fun findPurchaseUnitByM18ItemId(m18ItemId: Long): ItemUom? { | |||||
| return itemUomRespository.findByItemM18IdAndPurchaseUnitIsTrueAndDeletedIsFalse(m18ItemId) | |||||
| } | |||||
| // See if need to update the response | // See if need to update the response | ||||
| open fun saveItemUom(request: ItemUomRequest): ItemUom { | open fun saveItemUom(request: ItemUomRequest): ItemUom { | ||||
| val itemUom = request.m18Id?.let { findByM18Id(it) } ?: request.id?.let { findById(it) } ?: ItemUom() | val itemUom = request.m18Id?.let { findByM18Id(it) } ?: request.id?.let { findById(it) } ?: ItemUom() | ||||
| if (request.m18LastModifyDate == itemUom.m18LastModifyDate) { | |||||
| return itemUom | |||||
| } | |||||
| val item = request.itemId?.let { itemsService.find(it).getOrNull() } | val item = request.itemId?.let { itemsService.find(it).getOrNull() } | ||||
| val uom = request.m18UomId?.let { uomConversionService.findByM18Id(it) } ?: request.uomId?.let { uomConversionService.find(it).getOrNull() } | val uom = request.m18UomId?.let { uomConversionService.findByM18Id(it) } ?: request.uomId?.let { uomConversionService.find(it).getOrNull() } | ||||
| val currency = request.currencyId?.let { currencyService.findById(it) } | val currency = request.currencyId?.let { currencyService.findById(it) } | ||||
| @@ -51,7 +65,12 @@ open class ItemUomService( | |||||
| return savedItemUom | return savedItemUom | ||||
| } | } | ||||
| @Throws(IOException::class) | |||||
| @Transactional | |||||
| open fun deleteItemUoms(deleteIds: List<Long>) { | open fun deleteItemUoms(deleteIds: List<Long>) { | ||||
| itemUomRespository.deleteAllByIdIn(deleteIds) | |||||
| // println(deleteIds) | |||||
| if (deleteIds.isNotEmpty()) { | |||||
| itemUomRespository.deleteAllByIdIn(deleteIds) | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -48,15 +48,34 @@ open class ItemsService( | |||||
| return jdbcDao.queryForList(sql.toString(), args); | return jdbcDao.queryForList(sql.toString(), args); | ||||
| } | } | ||||
| open fun findById(id: Long): Items? { | |||||
| return itemsRepository.findByIdAndDeletedFalse(id); | |||||
| } | |||||
| open fun findByM18Id(m18Id: Long): Items? { | open fun findByM18Id(m18Id: Long): Items? { | ||||
| return itemsRepository.findByM18IdAndDeletedIsFalse(m18Id) | return itemsRepository.findByM18IdAndDeletedIsFalse(m18Id) | ||||
| } | } | ||||
| open fun findByNameLikeAndM18UomId(name: String, m18UomId: Long): Items? { | |||||
| return itemsRepository.findByNameLikeAndUomM18Id(name, m18UomId); | |||||
| } | |||||
| open fun findByNameExactlyAndM18UomId(name: String, m18UomId: Long): Items? { | |||||
| return itemsRepository.findByNameExactlyAndUomM18Id(name, m18UomId); | |||||
| } | |||||
| open fun findByNameAndM18UomId(name: String, m18UomId: Long): Items? { | |||||
| return findByNameExactlyAndM18UomId(name, m18UomId) ?: findByNameLikeAndM18UomId(name, m18UomId); | |||||
| } | |||||
| open fun findByM18BomCode(m18BomCode: String): Items? { | |||||
| return itemsRepository.findByM18BomCode(m18BomCode); | |||||
| } | |||||
| // QcCheck included item | // QcCheck included item | ||||
| open fun getItem(id: Long): ItemWithQcResponse { | open fun getItem(id: Long): ItemWithQcResponse { | ||||
| val list = listOf(1,2) | val list = listOf(1,2) | ||||
| val item = itemsRepository.findByIdAndDeletedFalse(id) | |||||
| val item = itemsRepository.findByIdAndDeletedFalse(id) ?: Items() | |||||
| val qcItems = qcItemsRepository.findAllByDeletedIsFalse() | val qcItems = qcItemsRepository.findAllByDeletedIsFalse() | ||||
| val qcCheckMap = qcCheckRepository.findAllByItemIdAndDeletedFalse(id).associateBy { it.id } | val qcCheckMap = qcCheckRepository.findAllByItemIdAndDeletedFalse(id).associateBy { it.id } | ||||
| val qc = qcItems.map { | val qc = qcItems.map { | ||||
| @@ -100,8 +119,19 @@ open class ItemsService( | |||||
| ) | ) | ||||
| } | } | ||||
| val item = if (request.m18Id != null) findByM18Id(request.m18Id) ?: Items() | val item = if (request.m18Id != null) findByM18Id(request.m18Id) ?: Items() | ||||
| else if (request.id != null && request.id > 0) itemsRepository.findByIdAndDeletedFalse(request.id) | |||||
| else if (request.id != null && request.id > 0) itemsRepository.findByIdAndDeletedFalse(request.id) ?: Items() | |||||
| else Items() | else Items() | ||||
| if (item.m18LastModifyDate == request.m18LastModifyDate) { | |||||
| return MessageResponse( | |||||
| id = item.id, | |||||
| code = item.code, | |||||
| name = item.name, | |||||
| type = item.type.toString(), | |||||
| message = "M18 Item does not have any updates", | |||||
| errorPosition = "m18LastModifyDate" | |||||
| ) | |||||
| } | |||||
| item.apply { | item.apply { | ||||
| code = request.code | code = request.code | ||||
| name = request.name | name = request.name | ||||
| @@ -21,26 +21,37 @@ open class ShopService( | |||||
| return shopRepository.findByIdAndDeletedIsFalse(id) | return shopRepository.findByIdAndDeletedIsFalse(id) | ||||
| } | } | ||||
| open fun findByM18Id(m18Id: Long): Shop? { | |||||
| return shopRepository.findByM18IdAndDeletedIsFalse(m18Id) | |||||
| open fun findVendorByM18Id(m18Id: Long): Shop? { | |||||
| return shopRepository.findByM18IdAndTypeAndDeletedIsFalse(m18Id, ShopType.SUPPLIER) | |||||
| } | } | ||||
| open fun findVendorIdsByCodeRegexp(code: List<String>): List<Long>? { | |||||
| open fun findM18VendorIdsByCodeRegexp(code: List<String>): List<Long>? { | |||||
| val codeRegexp = code.joinToString("|") | val codeRegexp = code.joinToString("|") | ||||
| return shopRepository.findIdsByCodeRegexpAndTypeAndDeletedIsFalse(codeRegexp, type = ShopType.SUPPLIER.value) | |||||
| return shopRepository.findM18IdsByCodeRegexpAndTypeAndDeletedIsFalse(codeRegexp, type = ShopType.SUPPLIER.value) | |||||
| } | } | ||||
| open fun findVendorIdsByCodeNotRegexp(code: List<String>): List<Long>? { | |||||
| open fun findM18VendorIdsByCodeNotRegexp(code: List<String>): List<Long>? { | |||||
| val codeRegexp = code.joinToString("|") | val codeRegexp = code.joinToString("|") | ||||
| return shopRepository.findIdsByCodeNotRegexpAndTypeAndDeletedIsFalse(codeRegexp, type = ShopType.SUPPLIER.value) | |||||
| return shopRepository.findM18IdsByCodeNotRegexpAndTypeAndDeletedIsFalse(codeRegexp, type = ShopType.SUPPLIER.value) | |||||
| } | } | ||||
| open fun saveShop(request: SaveShopRequest): SaveShopResponse { | open fun saveShop(request: SaveShopRequest): SaveShopResponse { | ||||
| val shop = if (request.m18Id != null) { | val shop = if (request.m18Id != null) { | ||||
| findByM18Id(request.m18Id) ?: Shop() | |||||
| findVendorByM18Id(request.m18Id) ?: Shop() | |||||
| } else { | } else { | ||||
| request.id?.let { shopRepository.findById(it).getOrDefault(Shop()) } ?: Shop() | request.id?.let { shopRepository.findById(it).getOrDefault(Shop()) } ?: Shop() | ||||
| } | } | ||||
| if (shop.m18LastModifyDate == request.m18LastModifyDate) { | |||||
| return shop.let { | |||||
| SaveShopResponse( | |||||
| id = it.id, | |||||
| code = it.code, | |||||
| name = it.name, | |||||
| ) | |||||
| } | |||||
| } | |||||
| val type = request.type?.let { type -> ShopType.entries.find { it.value == type } } | val type = request.type?.let { type -> ShopType.entries.find { it.value == type } } | ||||
| shop.apply { | shop.apply { | ||||
| @@ -196,6 +196,10 @@ open class UomConversionService( | |||||
| } | } | ||||
| } | } | ||||
| open fun findById(id: Long): UomConversion? { | |||||
| return uomConversionRepository.findByIdAndDeletedFalse(id) | |||||
| } | |||||
| open fun findByM18Id(m18Id: Long) : UomConversion? { | open fun findByM18Id(m18Id: Long) : UomConversion? { | ||||
| return uomConversionRepository.findByM18IdAndDeletedFalse(m18Id) | return uomConversionRepository.findByM18IdAndDeletedFalse(m18Id) | ||||
| } | } | ||||
| @@ -0,0 +1,21 @@ | |||||
| package com.ffii.fpsms.modules.master.web.models | |||||
| import java.math.BigDecimal | |||||
| import java.time.LocalDateTime | |||||
| data class SaveBomMaterialRequest( | |||||
| val id: Long? = null, | |||||
| val itemId: Long? = null, | |||||
| val m18ItemId: Long? = null, | |||||
| val itemName: String?, | |||||
| val isConsumable: Boolean = false, | |||||
| val qty: BigDecimal?, | |||||
| val uomId: Long? = null, | |||||
| val m18UomId: Long? = null, | |||||
| val uomName: String? = null, | |||||
| val bomId: Long? = null, | |||||
| val m18BomId: Long? = null, | |||||
| val m18Id: Long? = null, | |||||
| val m18LastModifyDate: LocalDateTime? = null, | |||||
| val remarks: String? = null | |||||
| ) | |||||
| @@ -0,0 +1,13 @@ | |||||
| package com.ffii.fpsms.modules.master.web.models | |||||
| import java.math.BigDecimal | |||||
| data class SaveBomMaterialResponse ( | |||||
| val id: Long?, | |||||
| val itemName: String?, | |||||
| val isConsumable: Boolean?, | |||||
| val qty: BigDecimal?, | |||||
| val uomName: String?, | |||||
| val bomCode: String?, | |||||
| val remarks: String?, | |||||
| ) | |||||
| @@ -0,0 +1,23 @@ | |||||
| package com.ffii.fpsms.modules.master.web.models | |||||
| import jakarta.validation.constraints.NotBlank | |||||
| import java.math.BigDecimal | |||||
| import java.time.LocalDateTime | |||||
| data class SaveBomRequest ( | |||||
| val id: Long? = null, | |||||
| @field:NotBlank(message = "bom code cannot be empty") | |||||
| val code: String, | |||||
| @field:NotBlank(message = "bom name cannot be empty") | |||||
| val name: String, | |||||
| @field:NotBlank(message = "bom description cannot be empty") | |||||
| val description: String, | |||||
| val itemId: Long? = null, | |||||
| val outputQty: BigDecimal? = null, | |||||
| val outputQtyUom: String? = null, | |||||
| val yield: BigDecimal? = null, | |||||
| val uomId: Long? = null, | |||||
| val m18UomId: Long? = null, | |||||
| val m18Id: Long? = null, | |||||
| val m18LastModifyDate: LocalDateTime? = null | |||||
| ) | |||||
| @@ -0,0 +1,14 @@ | |||||
| package com.ffii.fpsms.modules.master.web.models | |||||
| import java.math.BigDecimal | |||||
| data class SaveBomResponse ( | |||||
| val id: Long?, | |||||
| val code: String?, | |||||
| val name: String?, | |||||
| val description: String?, | |||||
| val outputQty: BigDecimal? = null, | |||||
| val outputQtyUom: String? = null, | |||||
| val yield: BigDecimal? = null, | |||||
| val uomName: String? = null, | |||||
| ) | |||||
| @@ -0,0 +1,12 @@ | |||||
| package com.ffii.fpsms.modules.master.web.models | |||||
| import java.time.LocalDateTime | |||||
| data class SaveCurrencyRequest ( | |||||
| val id: Long?, | |||||
| val code: String?, | |||||
| val name: String?, | |||||
| val description: String?, | |||||
| val m18Id: Long?, | |||||
| val m18LastModifyDate: LocalDateTime?, | |||||
| ) | |||||