MSI\derek 1 mese fa
parent
commit
52d2cbab5d
10 ha cambiato i file con 155 aggiunte e 22 eliminazioni
  1. +27
    -0
      src/main/java/com/ffii/fpsms/m18/entity/GrnSendLog.kt
  2. +6
    -0
      src/main/java/com/ffii/fpsms/m18/entity/GrnSendLogRepository.kt
  3. +7
    -0
      src/main/java/com/ffii/fpsms/m18/utils/CommonUtils.kt
  4. +9
    -5
      src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt
  5. +13
    -9
      src/main/java/com/ffii/fpsms/modules/master/service/ShopService.kt
  6. +47
    -3
      src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt
  7. +16
    -0
      src/main/java/com/ffii/fpsms/modules/purchaseOrder/web/model/PostGrnRequest.kt
  8. +1
    -0
      src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLineRepository.kt
  9. +12
    -5
      src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineService.kt
  10. +17
    -0
      src/main/resources/db/changelog/changes/20250724_derek/01_create_GRN_post_log.sql

+ 27
- 0
src/main/java/com/ffii/fpsms/m18/entity/GrnSendLog.kt Vedi File

@@ -0,0 +1,27 @@
package com.ffii.fpsms.m18.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
import org.hibernate.annotations.JdbcTypeCode
import org.hibernate.type.SqlTypes

@Entity
@Table(name = "grn_send_log")
open class GrnSendLog: BaseEntity<Long>() {
@Size(max = 1000)
@NotNull
@Column(name = "refType", nullable = false, length = 1000)
open var refType: String? = null

@JdbcTypeCode(SqlTypes.JSON)
@Column(name = "data")
open var data: MutableMap<String, Any?>? = null

@NotNull
@Column(name = "status")
open var status: Boolean? = null
}

+ 6
- 0
src/main/java/com/ffii/fpsms/m18/entity/GrnSendLogRepository.kt Vedi File

@@ -0,0 +1,6 @@
package com.ffii.fpsms.m18.entity

import com.ffii.core.support.AbstractRepository

interface GrnSendLogRepository: AbstractRepository<GrnSendLog, Long> {
}

+ 7
- 0
src/main/java/com/ffii/fpsms/m18/utils/CommonUtils.kt Vedi File

@@ -4,6 +4,7 @@ import com.ffii.fpsms.m18.M18Config
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Lazy
import org.springframework.stereotype.Component
import java.math.BigDecimal
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
@@ -32,4 +33,10 @@ open class CommonUtils(
}
return strings.joinToString(delimiter) { "$prefix$it" }
}

companion object {
fun getAmt(up: BigDecimal, discount: BigDecimal, qty: BigDecimal): Double {
return qty.times(BigDecimal(1) - discount).times(up).toDouble()
}
}
}

+ 9
- 5
src/main/java/com/ffii/fpsms/modules/master/service/ProductionScheduleService.kt Vedi File

@@ -338,12 +338,14 @@ open class ProductionScheduleService(
// Job Order Bom Material
val jobmRequests = bom.bomMaterials.map { bm ->
val demandQty = bm.qty?.times(proportion) ?: BigDecimal.ZERO
val saleUnit = bm.item?.id?.let { itemUomService.findSalesUnitByItemId(it) }
println("itemId: ${bm.item?.id} | itemNo: ${bm.item?.code} | itemName: ${bm.item?.name} | saleUnit: ${saleUnit?.uom?.udfudesc}")

val jobm = CreateJobOrderBomMaterialRequest(
joId = jo.id,
itemId = bm.item?.id,
reqQty = bm.qty?.times(proportion) ?: BigDecimal.ZERO,
uomId = bm.salesUnit?.id
uomId = saleUnit?.uom?.id
)

jobm
@@ -354,7 +356,7 @@ open class ProductionScheduleService(
}

// Inventory
val inventories = bom.bomMaterials.map { bm ->
/* val inventories = bom.bomMaterials.map { bm ->
val demandQty = bm.qty?.times(proportion) ?: BigDecimal.ZERO

var inventory = bm.item?.id?.let { inventoryRepository.findByItemId(it).getOrNull() }
@@ -388,7 +390,7 @@ open class ProductionScheduleService(
}
}

inventoryRepository.saveAllAndFlush(inventories)
inventoryRepository.saveAllAndFlush(inventories) */
}

// Create Job Order Process
@@ -874,12 +876,14 @@ open class ProductionScheduleService(
for (i in 5 until 12) {
try {
val prodSchedule = productionScheduleRepository.findById(parentId).get()
val item = roughScheduleObj.fgDetail?.id?.let { itemService.findById(it) } ?: Items()
val item = roughScheduleObj.fgDetail?.id?.let { itemService.findById(it) }
var savedItem = ProductionScheduleLine()
savedItem.id = -1;
// savedItem.prodScheduleId = parentId;
savedItem.productionSchedule = prodSchedule;
savedItem.item = item;
if (item != null) {
savedItem.item = item
};
savedItem.lastMonthAvgSales = roughScheduleObj.fgDetail?.lastMonthAvgSalesCount ?: 0.0;
savedItem.refScheduleId = null;
savedItem.approverId = null;


+ 13
- 9
src/main/java/com/ffii/fpsms/modules/master/service/ShopService.kt Vedi File

@@ -41,24 +41,28 @@ open class ShopService(

open fun saveShop(request: SaveShopRequest): SaveShopResponse {
val shop = if (request.m18Id != null) {
findVendorByM18Id(request.m18Id) ?: Shop()
when (request.type){
"supplier" -> findVendorByM18Id(request.m18Id) ?: Shop()
"shop" -> findShopByM18Id(request.m18Id) ?: Shop()
else -> Shop();
}
} else {
request.id?.let { shopRepository.findById(it).getOrDefault(Shop()) } ?: Shop()
}

if (shop.m18LastModifyDate == request.m18LastModifyDate) {
if (shop?.m18LastModifyDate == request.m18LastModifyDate) {
return shop.let {
SaveShopResponse(
id = it.id,
code = it.code,
name = it.name,
id = it?.id,
code = it?.code,
name = it?.name,
)
}
}

val type = request.type?.let { type -> ShopType.entries.find { it.value == type } }

shop.apply {
shop?.apply {
code = request.code
name = request.name
brNo = request.brNo
@@ -77,9 +81,9 @@ open class ShopService(

val response = shopRepository.saveAndFlush(shop).let {
SaveShopResponse(
id = it.id,
code = it.code,
name = it.name,
id = it?.id,
code = it?.code,
name = it?.name,
)
}



+ 47
- 3
src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt Vedi File

@@ -3,7 +3,10 @@ package com.ffii.fpsms.modules.purchaseOrder.service
import com.ffii.core.response.RecordsRes
import com.ffii.core.support.AbstractBaseEntityService
import com.ffii.core.support.JdbcDao
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.ShopRepository
import com.ffii.fpsms.modules.master.service.CurrencyService
import com.ffii.fpsms.modules.master.service.ShopService
@@ -17,19 +20,19 @@ 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.PagingRequest
import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderRequest
import com.ffii.fpsms.modules.purchaseOrder.web.model.SavePurchaseOrderResponse
import com.ffii.fpsms.modules.purchaseOrder.web.model.*
import com.ffii.fpsms.modules.stock.entity.StockInLine
import com.ffii.fpsms.modules.stock.entity.StockInLineRepository
import com.ffii.fpsms.modules.stock.entity.StockInRepository
import com.ffii.fpsms.modules.stock.web.model.StockInLineStatus
import com.google.gson.Gson
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.io.IOException
import java.math.BigDecimal
import java.time.LocalDateTime
import java.util.HashMap
import java.util.Objects
@@ -47,6 +50,7 @@ open class PurchaseOrderService(
private val stockInLineRepository: StockInLineRepository,
private val currencyService: CurrencyService,
private val shopService: ShopService,
private val grnSendLogRepository: GrnSendLogRepository,
) : AbstractBaseEntityService<PurchaseOrder, Long, PurchaseOrderRepository>(jdbcDao, purchaseOrderRepository) {
// open fun getPurchaseOrderInfo(args: Map<String, Any>): List<Map<String, Any>> {
// val sql = StringBuilder(
@@ -91,6 +95,7 @@ open class PurchaseOrderService(
sql.append(" and sil.purchaseOrderId IS NULL ");
}
}
sql.append(" order by po.orderDate desc")
val list = jdbcDao.queryForList(sql.toString(), args);
println(list)

@@ -226,6 +231,10 @@ open class PurchaseOrderService(
@Transactional
open fun checkPolAndCompletePo(id: Long): MessageResponse {
val unfinishedLines = polRepository.findAllByPurchaseOrderIdAndStatusNotAndDeletedIsFalse(purchaseOrderId = id, status = PurchaseOrderLineStatus.COMPLETED)
// val purchaseOrderLine = polRepository.findAllByPurchaseOrderIdAndDeletedIsFalse(purchaseOrderId = id)
// val unfinishedLines = purchaseOrderLine.filter {
// it.status != PurchaseOrderLineStatus.COMPLETED
// }
// val unfinishedLines = polRepository.findAllByPurchaseOrderIdAndDeletedIsFalse(purchaseOrderId = id)
// .filter {
// it.status != PurchaseOrderLineStatus.COMPLETED |
@@ -233,12 +242,47 @@ open class PurchaseOrderService(
// }
println("unfinishedLines")
println(unfinishedLines)

val po = purchaseOrderRepository.findById(id).orElseThrow()
if (unfinishedLines.isEmpty()) {
val stockInLines = stockInLineRepository.findAllByPurchaseOrderIdAndDeletedFalse(po.id).orElseThrow()
po.apply {
status = PurchaseOrderStatus.COMPLETED
}
val savedPo = purchaseOrderRepository.saveAndFlush(po)
// map request
val antRequest = stockInLines.map {
Ant(
proCode = it.itemNo!!,
unitCode = it.purchaseOrderLine!!.uom!!.code!!,
locCode = it.inventoryLotLine!!.warehouse!!.code!!,
qty = it.acceptedQty!!.toDouble(),
up = (it.purchaseOrderLine!!.up ?: 0.0).toDouble(),
amt = CommonUtils.getAmt(
up = (it.purchaseOrderLine!!.up ?: BigDecimal(0)),
discount = it.purchaseOrderLine!!.m18Discount ?: BigDecimal(0),
qty = it.acceptedQty!!
)
)
}
val postGrnRequest = PostGrnRequest(
beId = po!!.m18BeId!!,
venCode = po.supplier!!.code!!,
ant = antRequest
)
// post grn api
// log in grn send log
val grnSendLog = GrnSendLog().apply {
this.refType = "purchase order"
this.data = mutableMapOf(
"beId" to postGrnRequest.beId,
"venCode" to postGrnRequest.venCode,
"ant" to postGrnRequest.ant,
)
this.status = true
}
grnSendLogRepository.save(grnSendLog)

return MessageResponse(
id = savedPo.id,
name = savedPo.code,


+ 16
- 0
src/main/java/com/ffii/fpsms/modules/purchaseOrder/web/model/PostGrnRequest.kt Vedi File

@@ -0,0 +1,16 @@
package com.ffii.fpsms.modules.purchaseOrder.web.model

data class Ant( // stock in line
val proCode: String,
val unitCode: String,
val locCode: String,
val qty: Double,
val up: Double,
val amt: Double,
)
data class PostGrnRequest(
val beId: Long,
val venCode: String,
val ant: List<Ant>

)

+ 1
- 0
src/main/java/com/ffii/fpsms/modules/stock/entity/StockInLineRepository.kt Vedi File

@@ -16,4 +16,5 @@ interface StockInLineRepository : AbstractRepository<StockInLine, Long> {
fun findStockInLineInfoByPurchaseOrderLineIdAndDeletedFalse(purchaseOrderLineId: Long): List<StockInLineInfo>
fun findStockInLineInfoByIdAndStatusAndDeletedFalse(id: Long, status: String): Optional<StockInLineInfo>
fun findAllStockInLineInfoByPurchaseOrderIdAndStatusStartsWithAndDeletedFalse(purchaseOrderId: Long, status: String): List<Optional<StockInLineInfo>>
fun findAllByPurchaseOrderIdAndDeletedFalse(purchaseOrderId: Long): Optional<List<StockInLine>>
}

+ 12
- 5
src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineService.kt Vedi File

@@ -2,6 +2,7 @@ package com.ffii.fpsms.modules.stock.service

import com.ffii.core.support.AbstractBaseEntityService
import com.ffii.core.support.JdbcDao
import com.ffii.fpsms.modules.master.entity.ItemUomRespository
import com.ffii.fpsms.modules.master.entity.ItemsRepository
import com.ffii.fpsms.modules.master.web.models.MessageResponse
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLineRepository
@@ -25,6 +26,7 @@ open class StockOutLineService(
private val stockOutLineRepository: StockOutLIneRepository,
private val itemRepository: ItemsRepository,
private val inventoryRepository: InventoryRepository,
private val itemUomRespository: ItemUomRespository,
private val inventoryLotLineRepository: InventoryLotLineRepository
): AbstractBaseEntityService<StockOutLine, Long, StockOutLIneRepository>(jdbcDao, stockOutLineRepository) {
@Throws(IOException::class)
@@ -117,19 +119,24 @@ open class StockOutLineService(
this.status = StockOutLineStatus.COMPLETE.status // complete
}
// update inventory lot line
val zero = BigDecimal.ZERO
val one = BigDecimal.ONE
val targetLotLine = inventoryLotLineRepository.findById(request.inventoryLotLineId!!).orElseThrow()
val salesUnit = inventoryLotLine?.inventoryLot?.item?.id?.let {_itemId -> itemUomRespository.findByItemIdAndSalesUnitIsTrueAndDeletedIsFalse(_itemId) }
val ratio = (salesUnit?.ratioN ?: zero).divide(salesUnit?.ratioD ?: one).toDouble()
val targetLotLineEntry = targetLotLine.apply {
this.outQty = (this.outQty?: BigDecimal.ZERO) + request.qty.toBigDecimal()
this.holdQty = this.holdQty!!.minus(request.qty.toBigDecimal())

this.outQty = (this.outQty?: BigDecimal.ZERO) + (request.qty.div(ratio)).toBigDecimal()
this.holdQty = this.holdQty!!.minus((request.qty.div(ratio)).toBigDecimal())
}
inventoryLotLineRepository.save(targetLotLineEntry)
// update inventory
val inventory = inventoryRepository.findByItemId(request.itemId).orElseThrow()
val inventoryEntry = inventory.apply {
this.onHandQty = this.onHandQty!!.minus(request.qty.toBigDecimal())
this.onHoldQty = this.onHoldQty!!.minus(request.qty.toBigDecimal())
this.onHandQty = this.onHandQty!!.minus((request.qty.div(ratio)).toBigDecimal())
this.onHoldQty = this.onHoldQty!!.minus((request.qty.div(ratio)).toBigDecimal())
}
inventoryRepository.save(inventoryEntry)
return listOf(stockOutLine, newStockOutLine)
}
@Transactional


+ 17
- 0
src/main/resources/db/changelog/changes/20250724_derek/01_create_GRN_post_log.sql Vedi File

@@ -0,0 +1,17 @@
--liquibase formatted sql

--changeset derek:grn psot log
CREATE TABLE `grn_send_log`
(
`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',
`refType` VARCHAR(1000) NOT NULL,
`data` JSON NOT NULL,
`status` TINYINT(1) NOT NULL,
CONSTRAINT pk_grn_post_log PRIMARY KEY (id)
);

Caricamento…
Annulla
Salva