@@ -28,7 +28,7 @@ open class JobOrderBomMaterial : BaseEntity<Long>() { | |||
@Column(name = "reqQty", nullable = false, precision = 14, scale = 2) | |||
open var reqQty: BigDecimal? = null | |||
@NotNull | |||
// @NotNull | |||
@ManyToOne | |||
@JoinColumn(name = "uomId", nullable = false) | |||
open var uom: UomConversion? = null | |||
@@ -1,10 +1,41 @@ | |||
package com.ffii.fpsms.modules.master.entity | |||
import com.ffii.core.support.AbstractRepository | |||
import com.ffii.fpsms.modules.master.entity.projections.DetailedProdScheduleLineBomMaterial | |||
import com.ffii.fpsms.modules.master.entity.projections.DetailedProdScheduleLineBomMaterialInterface | |||
import org.springframework.data.jpa.repository.Query | |||
import org.springframework.stereotype.Repository | |||
import java.time.LocalDateTime | |||
@Repository | |||
interface ProductionScheduleLineRepository : AbstractRepository<ProductionScheduleLine, Long> { | |||
@Query(nativeQuery = true, | |||
value = """ | |||
with prod_prop as ( | |||
select | |||
psl.id as pslId, | |||
round(coalesce(psl.prodQty, 0) / coalesce(b.outputQty, 1), 2) as proportion | |||
from production_schedule_line psl | |||
left join bom b on b.itemId = psl.itemId | |||
where psl.id = :id and b.id is not null | |||
) | |||
select | |||
psl.id as pslId, | |||
bm.id, | |||
b.outputQty as bomOutputQty, | |||
bmi.code, | |||
bmi.name, | |||
bmi.`type`, | |||
coalesce(i.onHandQty, 0) - coalesce(i.onHoldQty, 0) - coalesce(i.unavailableQty, 0) as availableQty, | |||
ceil(coalesce(bm.qty, 0) * pp.proportion) as demandQty | |||
from production_schedule_line psl | |||
left join prod_prop pp on pp.pslId = psl.id | |||
left join bom b on b.itemId = psl.itemId | |||
left join bom_material bm on bm.bomId = b.id | |||
left join items bmi on bmi.id = bm.itemId | |||
left join inventory i on i.itemId = bmi.id | |||
where psl.id = :id and bmi.id is not null | |||
group by psl.id, bm.id, i.id, pp.proportion | |||
""") | |||
fun getBomMaterials(id: Long): List<DetailedProdScheduleLineBomMaterialInterface>? | |||
} |
@@ -1,9 +1,7 @@ | |||
package com.ffii.fpsms.modules.master.entity | |||
import com.ffii.core.support.AbstractRepository | |||
import com.ffii.fpsms.modules.master.entity.projections.DetailedProdScheduleWithLine | |||
import com.ffii.fpsms.modules.master.entity.projections.DetailedProdScheduleWithLineWithJsonString | |||
import com.ffii.fpsms.modules.master.entity.projections.ProdScheduleInfo | |||
import com.ffii.fpsms.modules.master.entity.projections.* | |||
import org.springframework.data.domain.Page | |||
import org.springframework.data.domain.Pageable | |||
import org.springframework.data.jpa.repository.Query | |||
@@ -85,7 +83,7 @@ interface ProductionScheduleRepository : AbstractRepository<ProductionSchedule, | |||
with prod_prop as ( | |||
select | |||
psl.id as pslId, | |||
coalesce(psl.prodQty, 0) / coalesce(b.outputQty, 1) as proportion | |||
round(coalesce(psl.prodQty, 0) / coalesce(b.outputQty, 1), 2) as proportion | |||
from production_schedule ps | |||
left join production_schedule_line psl on psl.prodScheduleId = ps.id | |||
left join bom b on b.itemId = psl.itemId | |||
@@ -99,7 +97,8 @@ interface ProductionScheduleRepository : AbstractRepository<ProductionSchedule, | |||
select | |||
psl.id as pslId, | |||
coalesce(e.name, 'N/A') as equipName, | |||
ceil(sum((coalesce(bp.prepTimeInMinute, 0) + coalesce(bp.durationInMinute, 0) + coalesce(bp.postProdTimeInMinute, 0)) * pp.proportion)) as totalMinutes | |||
-- ceil(sum((coalesce(bp.prepTimeInMinute, 0) + coalesce(bp.durationInMinute, 0) + coalesce(bp.postProdTimeInMinute, 0)) * pp.proportion)) as totalMinutes | |||
sum(coalesce(bp.prepTimeInMinute, 0) + coalesce(bp.durationInMinute, 0) + coalesce(bp.postProdTimeInMinute, 0)) as totalMinutes | |||
from production_schedule ps | |||
left join production_schedule_line psl on psl.prodScheduleId = ps.id | |||
left join prod_prop pp on pp.pslId = psl.id | |||
@@ -114,16 +113,19 @@ interface ProductionScheduleRepository : AbstractRepository<ProductionSchedule, | |||
prod_material as ( | |||
select | |||
r2.pslId, | |||
r2.bomOutputQty, | |||
json_arrayagg(json_object('id', r2.id, 'code', r2.code, 'name', r2.name, 'type', r2.`type`, 'availableQty', r2.availableQty, 'demandQty', r2.demandQty)) as bomMaterials | |||
from ( | |||
select | |||
psl.id as pslId, | |||
bm.id, | |||
b.outputQty as bomOutputQty, | |||
bmi.code, | |||
bmi.name, | |||
bmi.`type`, | |||
coalesce(i.onHandQty, 0) - coalesce(i.onHoldQty, 0) - coalesce(i.unavailableQty, 0) as availableQty, | |||
ceil(coalesce(bm.qty, 0) * pp.proportion) as demandQty | |||
-- ceil(coalesce(bm.qty, 0) * pp.proportion) as demandQty | |||
coalesce(bm.qty, 0) * pp.proportion as demandQty | |||
from production_schedule ps | |||
left join production_schedule_line psl on psl.prodScheduleId = ps.id | |||
left join prod_prop pp on pp.pslId = psl.id | |||
@@ -134,7 +136,7 @@ interface ProductionScheduleRepository : AbstractRepository<ProductionSchedule, | |||
where ps.id = :id and bmi.id is not null | |||
group by ps.id, psl.id, bm.id, i.id, pp.proportion | |||
) r2 | |||
group by r2.pslId | |||
group by r2.pslId, r2.bomOutputQty | |||
) | |||
select | |||
prod.id, | |||
@@ -142,7 +144,7 @@ interface ProductionScheduleRepository : AbstractRepository<ProductionSchedule, | |||
prod.totalFGType, | |||
prod.totalEstProdCount, | |||
json_arrayagg( | |||
json_object('id', prod.pslId, 'bomMaterials', prod.bomMaterials, 'jobNo', prod.jobNo, 'code', prod.code, 'name', prod.name, 'type', prod.type, 'demandQty', prod.demandQty, 'prodTimeInMinute', prod.prodTimeInMinute, 'priority', prod.priority) | |||
json_object('id', prod.pslId, 'bomMaterials', prod.bomMaterials, 'jobNo', prod.jobNo, 'code', prod.code, 'name', prod.name, 'type', prod.type, 'demandQty', prod.demandQty, 'bomOutputQty', prod.bomOutputQty, 'prodTimeInMinute', prod.prodTimeInMinute, 'priority', prod.priority, 'approved', prod.approved, 'proportion', prod.proportion) | |||
) as prodScheduleLines | |||
from ( | |||
select | |||
@@ -150,24 +152,28 @@ interface ProductionScheduleRepository : AbstractRepository<ProductionSchedule, | |||
ps.scheduleAt, | |||
ps.totalFGType, | |||
ps.totalEstProdCount, | |||
psl.approverId is not null as approved, | |||
psl.id as pslId, | |||
pm.bomMaterials, | |||
pm.bomOutputQty, | |||
coalesce(jo.code, 'N/A') as jobNo, | |||
psli.code, | |||
psli.name, | |||
psli.`type`, | |||
psl.prodQty as demandQty, | |||
pe.prodTimeInMinute, | |||
psl.itemPriority as priority | |||
psl.itemPriority as priority, | |||
pp.proportion | |||
from production_schedule ps | |||
left join production_schedule_line psl on psl.prodScheduleId = ps.id | |||
left join items psli on psli.id = psl.itemId | |||
left join job_order jo on jo.prodScheduleLineId = psl.id | |||
left join prod_prop pp on pp.pslId = psl.id | |||
left join prod_equip pe on pe.pslId = psl.id | |||
left join prod_material pm on pm.pslId = psl.id | |||
where psl.deleted is false and pe.prodTimeInMinute is not null and pm.bomMaterials is not null | |||
and ps.id = :id | |||
group by psl.id, jo.id | |||
group by psl.id, jo.id, pp.proportion, pm.bomOutputQty | |||
) prod group by prod.id limit 1 | |||
""" | |||
) | |||
@@ -40,8 +40,11 @@ data class DetailedProdScheduleLineInfo( | |||
val name: String?, | |||
val type: String?, | |||
val demandQty: BigDecimal?, | |||
val bomOutputQty: BigDecimal?, | |||
val prodTimeInMinute: List<DetailedProdScheduleLineProdTime>?, | |||
val priority: BigDecimal? | |||
val priority: BigDecimal?, | |||
val approved: Boolean?, | |||
val proportion: BigDecimal? | |||
) | |||
data class DetailedProdScheduleLineBomMaterial ( | |||
@@ -53,6 +56,15 @@ data class DetailedProdScheduleLineBomMaterial ( | |||
val demandQty: BigDecimal? | |||
) | |||
interface DetailedProdScheduleLineBomMaterialInterface { | |||
val id: Long? | |||
val code: String? | |||
val name: String? | |||
val type: String? | |||
val availableQty: BigDecimal? | |||
val demandQty: BigDecimal? | |||
} | |||
data class DetailedProdScheduleLineProdTime ( | |||
val equipName: String?, | |||
val totalMinutes: BigDecimal? | |||
@@ -15,15 +15,23 @@ import com.ffii.fpsms.modules.master.entity.projections.* | |||
import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||
import com.ffii.fpsms.modules.master.web.models.ReleaseProdScheduleLineRequest | |||
import com.ffii.fpsms.modules.master.web.models.SearchProdScheduleRequest | |||
import com.ffii.fpsms.modules.stock.entity.Inventory | |||
import com.ffii.fpsms.modules.stock.entity.InventoryRepository | |||
import com.ffii.fpsms.modules.stock.service.InventoryService | |||
import com.google.gson.Gson | |||
import com.google.gson.GsonBuilder | |||
import com.google.gson.JsonDeserializationContext | |||
import com.google.gson.JsonDeserializer | |||
import com.google.gson.JsonElement | |||
import com.google.gson.reflect.TypeToken | |||
import org.springframework.data.domain.PageRequest | |||
import org.springframework.stereotype.Service | |||
import org.springframework.transaction.annotation.Transactional | |||
import java.lang.reflect.Type | |||
import java.math.BigDecimal | |||
import java.math.RoundingMode | |||
import java.time.LocalDateTime | |||
import java.time.format.DateTimeFormatter | |||
import java.util.* | |||
import kotlin.NoSuchElementException | |||
import kotlin.collections.component1 | |||
import kotlin.collections.component2 | |||
import kotlin.jvm.optionals.getOrNull | |||
@@ -41,6 +49,9 @@ open class ProductionScheduleService( | |||
private val jobOrderBomMaterialService: JobOrderBomMaterialService, | |||
private val bomService: BomService, | |||
private val jobOrderProcessService: JobOrderProcessService, | |||
private val inventoryService: InventoryService, | |||
private val inventoryRepository: InventoryRepository, | |||
private val itemUomService: ItemUomService | |||
) : AbstractBaseEntityService<ProductionSchedule, Long, ProductionScheduleRepository>( | |||
jdbcDao, | |||
productionScheduleRepository | |||
@@ -90,7 +101,7 @@ open class ProductionScheduleService( | |||
// BigDecimal.ONE | |||
// } | |||
val proportion = BigDecimal(line.prodQty).divide(bm.bom?.outputQty ?: BigDecimal.ONE) | |||
val proportion = BigDecimal(line.prodQty).divide(bm.bom?.outputQty ?: BigDecimal.ONE, 2, RoundingMode.HALF_UP) | |||
val demandQty = bm.qty?.times(proportion) ?: zero | |||
@@ -174,7 +185,7 @@ open class ProductionScheduleService( | |||
// BigDecimal.ONE | |||
// } | |||
val proportion = BigDecimal(line.prodQty).divide(bm.bom?.outputQty ?: BigDecimal.ONE) | |||
val proportion = BigDecimal(line.prodQty).divide(bm.bom?.outputQty ?: BigDecimal.ONE, 2, RoundingMode.HALF_UP) | |||
val demandQty = bm.qty?.times(proportion) ?: zero | |||
@@ -254,10 +265,19 @@ open class ProductionScheduleService( | |||
) | |||
} | |||
class BooleanTypeAdapter: JsonDeserializer<Boolean> { | |||
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Boolean { | |||
// println(json) | |||
return json.asInt == 1 | |||
} | |||
} | |||
open fun detailedProdScheduleDetail(id: Long): DetailedProdScheduleWithLine { | |||
val sqlResult = productionScheduleRepository.findDetailedProdScheduleWithLine(id) ?: throw NoSuchElementException() | |||
val gson = Gson() | |||
val gson = GsonBuilder() | |||
.registerTypeAdapter(Boolean::class.javaObjectType, BooleanTypeAdapter()) | |||
.create() | |||
val type = object : TypeToken<List<DetailedProdScheduleLineInfo>?>() {}.type | |||
val gsonResult: List<DetailedProdScheduleLineInfo>? = gson.fromJson(sqlResult.prodScheduleLines, type) | |||
@@ -270,14 +290,41 @@ open class ProductionScheduleService( | |||
) | |||
} | |||
@Transactional(rollbackFor = [java.lang.Exception::class]) | |||
open fun saveProdScheduleLine(request: ReleaseProdScheduleLineRequest): MessageResponse { | |||
val prodScheduleLine = request.id.let { productionScheduleLineRepository.findById(it).getOrNull() } ?: throw NoSuchElementException() | |||
// Update Prod Schedule Line Prod qty | |||
prodScheduleLine.apply { | |||
prodQty = request.demandQty.toDouble() | |||
} | |||
productionScheduleLineRepository.saveAndFlush(prodScheduleLine) | |||
val bomMaterials = prodScheduleLine.id?.let { productionScheduleLineRepository.getBomMaterials(it) } | |||
return MessageResponse( | |||
id = request.id, | |||
name = null, | |||
code = null, | |||
type = null, | |||
message = "Success", | |||
entity = mapOf("bomMaterials" to bomMaterials), | |||
errorPosition = null | |||
) | |||
} | |||
@Transactional(rollbackFor = [java.lang.Exception::class]) | |||
open fun releaseProdScheduleLine(request: ReleaseProdScheduleLineRequest): MessageResponse { | |||
val prodScheduleLine = request.id.let { productionScheduleLineRepository.findById(it).getOrNull() } ?: throw NoSuchElementException() | |||
val bom = prodScheduleLine.item.id?.let { bomService.findByItemId(it) } | |||
val approver = SecurityUtils.getUser().getOrNull() | |||
val proportion = request.demandQty.divide(bom?.outputQty ?: BigDecimal.ONE) | |||
val proportion = request.demandQty.divide(bom?.outputQty ?: BigDecimal.ONE, 2, RoundingMode.HALF_UP) | |||
// Update Prod Schedule Line Prod qty | |||
prodScheduleLine.apply { prodQty = request.demandQty.toDouble() } | |||
prodScheduleLine.apply { | |||
prodQty = request.demandQty.toDouble() | |||
approverId = approver?.id | |||
} | |||
productionScheduleLineRepository.save(prodScheduleLine) | |||
// Create Job Order | |||
@@ -291,16 +338,61 @@ open class ProductionScheduleService( | |||
val jo = jobOrderService.createJobOrder(joRequest) | |||
// Create Job Order Bom Materials | |||
val jobmRequests = bom?.bomMaterials?.map { bm -> | |||
CreateJobOrderBomMaterialRequest( | |||
joId = jo.id, | |||
itemId = bm.item?.id, | |||
reqQty = bm.qty?.times(proportion) ?: BigDecimal.ZERO, | |||
uomId = bm.uom?.id | |||
) | |||
} | |||
if (jobmRequests != null) { | |||
jobOrderBomMaterialService.createJobOrderBomMaterials(jobmRequests) | |||
if (bom?.bomMaterials != null) { | |||
// Job Order Bom Material | |||
val jobmRequests = bom.bomMaterials.map { bm -> | |||
val demandQty = bm.qty?.times(proportion) ?: BigDecimal.ZERO | |||
val jobm = CreateJobOrderBomMaterialRequest( | |||
joId = jo.id, | |||
itemId = bm.item?.id, | |||
reqQty = bm.qty?.times(proportion) ?: BigDecimal.ZERO, | |||
uomId = bm.salesUnit?.id | |||
) | |||
jobm | |||
} | |||
if (jobmRequests != null) { | |||
jobOrderBomMaterialService.createJobOrderBomMaterials(jobmRequests) | |||
} | |||
// Inventory | |||
val inventories = bom.bomMaterials.map { bm -> | |||
val demandQty = bm.qty?.times(proportion) ?: BigDecimal.ZERO | |||
var inventory = bm.item?.id?.let { inventoryRepository.findByItemId(it).getOrNull() } | |||
if (inventory != null) { | |||
inventory.apply { | |||
this.onHoldQty = (this.onHoldQty ?: BigDecimal.ZERO).plus(demandQty) | |||
} | |||
} else { | |||
if (bm.item != null) { | |||
val itemUom = bm.item?.id?.let { itemUomService.findSalesUnitByItemId(it) } | |||
inventory = Inventory().apply { | |||
item = bm.item | |||
onHandQty = BigDecimal.ZERO | |||
unavailableQty = BigDecimal.ZERO | |||
this.onHoldQty = demandQty | |||
uom = itemUom?.uom | |||
status = "unavailable" | |||
} | |||
} | |||
} | |||
inventory | |||
}.groupBy { it?.item } // Group by item | |||
.mapNotNull { (item, invList) -> | |||
if (invList.isNotEmpty()) { | |||
invList[0]?.apply { | |||
onHoldQty = invList.sumOf { it?.onHoldQty ?: BigDecimal.ZERO } | |||
} | |||
} else { | |||
null | |||
} | |||
} | |||
inventoryRepository.saveAllAndFlush(inventories) | |||
} | |||
// Create Job Order Process | |||
@@ -316,12 +408,17 @@ open class ProductionScheduleService( | |||
jobOrderProcessService.createJobOrderProcesses(jopRequests) | |||
} | |||
// Get Latest Data | |||
// val bomMaterials = prodScheduleLine.id?.let { productionScheduleLineRepository.getBomMaterials(it) } | |||
val latestDetail = prodScheduleLine.productionSchedule.id?.let { detailedProdScheduleDetail(it) } | |||
return MessageResponse( | |||
id = request.id, | |||
name = null, | |||
code = null, | |||
code = jo.code, | |||
type = null, | |||
message = "Success", | |||
entity = mapOf("prodScheduleLines" to latestDetail?.prodScheduleLines), | |||
errorPosition = null | |||
) | |||
} | |||
@@ -13,6 +13,7 @@ import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||
import com.ffii.fpsms.modules.master.web.models.ReleaseProdScheduleLineRequest | |||
import com.ffii.fpsms.modules.master.web.models.SearchProdScheduleRequest | |||
import jakarta.servlet.http.HttpServletRequest | |||
import jakarta.validation.Valid | |||
import org.springframework.web.bind.annotation.* | |||
import java.time.Duration | |||
import java.time.LocalDateTime | |||
@@ -54,15 +55,22 @@ class ProductionScheduleController( | |||
return productionScheduleService.detailedProdScheduleDetail(id) | |||
} | |||
@PostMapping("/detail/detailed/save") | |||
fun saveDetailedProdScheduleDetail(@Valid @RequestBody request: ReleaseProdScheduleLineRequest): MessageResponse { | |||
return productionScheduleService.saveProdScheduleLine(request) | |||
} | |||
@PostMapping("/detail/detailed/releaseLine") | |||
fun releaseProdScheduleLine(@Valid @RequestBody request: ReleaseProdScheduleLineRequest): MessageResponse { | |||
return productionScheduleService.releaseProdScheduleLine(request) | |||
} | |||
@GetMapping("/getRecordByPage") | |||
fun allProdSchedulesByPage(@ModelAttribute request: SearchProdScheduleRequest): RecordsRes<ProdScheduleInfo> { | |||
return productionScheduleService.allProdSchedulesByPage(request); | |||
} | |||
@PostMapping("/releaseLine") | |||
fun releaseProdScheduleLine(request: ReleaseProdScheduleLineRequest): MessageResponse { | |||
return productionScheduleService.releaseProdScheduleLine(request) | |||
} | |||
@RequestMapping(value = ["/testDetailSchedule"], method = [RequestMethod.GET]) | |||
fun generateDetailSchedule(request: HttpServletRequest?): Int { | |||
@@ -1,8 +1,11 @@ | |||
package com.ffii.fpsms.modules.master.web.models | |||
import jakarta.validation.constraints.NotNull | |||
import java.math.BigDecimal | |||
data class ReleaseProdScheduleLineRequest( | |||
@field:NotNull(message = "Id cannot be null") | |||
val id: Long, | |||
@field:NotNull(message = "Demand Qty cannot be null") | |||
val demandQty: BigDecimal, | |||
) |
@@ -29,8 +29,8 @@ class PurchaseOrderController( | |||
// @RequestParam(required = false) pageNum: Int, | |||
// @RequestParam(required = false) pageSize: Int | |||
): RecordsRes<PurchaseOrderDataClass> { | |||
println("request") | |||
println(request) | |||
// println("request") | |||
// println(request) | |||
val criteriaArgs = CriteriaArgsBuilder.withRequest(request) | |||
.addStringLike("code") | |||
.addString("status") | |||
@@ -11,19 +11,19 @@ import java.math.BigDecimal | |||
@Entity | |||
@Table(name = "inventory") | |||
open class Inventory: BaseEntity<Long>(){ | |||
@NotNull | |||
// @NotNull | |||
@Column(name = "onHandQty") | |||
open var onHandQty: BigDecimal? = null | |||
@NotNull | |||
// @NotNull | |||
@Column(name = "onHoldQty") | |||
open var onHoldQty: BigDecimal? = null | |||
@NotNull | |||
// @NotNull | |||
@Column(name = "unavailableQty") | |||
open var unavailableQty: BigDecimal? = null | |||
@NotNull | |||
// @NotNull | |||
@Column(name = "price") | |||
open var price: BigDecimal? = null | |||
@@ -35,23 +35,23 @@ open class Inventory: BaseEntity<Long>(){ | |||
@JoinColumn(name = "currencyId") | |||
open var currency: Currency? = null | |||
@NotNull | |||
// @NotNull | |||
@Column(name = "cpu") // cost per unit | |||
open var cpu: BigDecimal? = null | |||
@NotNull | |||
// @NotNull | |||
@Column(name = "cpuUnit") | |||
open var cpuUnit: String? = null | |||
@NotNull | |||
// @NotNull | |||
@Column(name = "cpm") // cost per unit | |||
open var cpm: BigDecimal? = null | |||
@NotNull | |||
// @NotNull | |||
@Column(name = "cpmUnit") | |||
open var cpmUnit: String? = null | |||
@NotNull | |||
// @NotNull | |||
@ManyToOne | |||
@JoinColumn(name = "uomId") | |||
open var uom: UomConversion? = null | |||
@@ -5,6 +5,9 @@ import com.ffii.core.support.JdbcDao | |||
import com.ffii.fpsms.modules.common.CodeGenerator | |||
import com.ffii.fpsms.modules.master.entity.Items | |||
import com.ffii.fpsms.modules.master.entity.ItemsRepository | |||
import com.ffii.fpsms.modules.master.entity.UomConversionRepository | |||
import com.ffii.fpsms.modules.master.service.ItemUomService | |||
import com.ffii.fpsms.modules.master.service.UomConversionService | |||
import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||
import com.ffii.fpsms.modules.stock.entity.Inventory | |||
import com.ffii.fpsms.modules.stock.entity.InventoryRepository | |||
@@ -12,14 +15,19 @@ import com.ffii.fpsms.modules.stock.entity.projection.InventoryInfo | |||
import com.ffii.fpsms.modules.stock.web.model.SaveInventoryRequest | |||
import org.springframework.stereotype.Service | |||
import java.io.IOException | |||
import java.math.BigDecimal | |||
import java.time.LocalDate | |||
import java.time.format.DateTimeFormatter | |||
import kotlin.jvm.optionals.getOrNull | |||
@Service | |||
open class InventoryService( | |||
private val jdbcDao: JdbcDao, | |||
private val inventoryRepository: InventoryRepository, | |||
private val itemsRepository: ItemsRepository, | |||
private val uomConversionService: UomConversionService, | |||
private val uomConversionRepository: UomConversionRepository, | |||
private val itemUomService: ItemUomService, | |||
): AbstractBaseEntityService<Inventory, Long, InventoryRepository>(jdbcDao, inventoryRepository) { | |||
open fun allInventory(): List<Inventory> { | |||
// TODO: Replace by actual logic | |||
@@ -39,6 +47,7 @@ open class InventoryService( | |||
return inventoryRepository.findInventoryInfoByItemIdInAndDeletedIsFalse(itemIds); | |||
} | |||
// @Throws(IOException::class) | |||
// open fun updateInventory(request: SaveInventoryRequest): MessageResponse { | |||
// // out need id | |||
@@ -0,0 +1,11 @@ | |||
-- liquibase formatted sql | |||
-- changeset cyril:update_job_order_bom_material | |||
ALTER TABLE `job_order_bom_material` | |||
DROP FOREIGN KEY `FK_JOBM_TO_UOM_CONVERSION_ON_UOM_ID`; | |||
ALTER TABLE `job_order_bom_material` | |||
CHANGE COLUMN `uomId` `uomId` INT NULL ; | |||
ALTER TABLE `job_order_bom_material` | |||
ADD CONSTRAINT `FK_JOBM_TO_UOM_CONVERSION_ON_UOM_ID` | |||
FOREIGN KEY (`uomId`) | |||
REFERENCES `uom_conversion` (`id`); |
@@ -0,0 +1,19 @@ | |||
-- liquibase formatted sql | |||
-- changeset cyril:update_inventory_default | |||
ALTER TABLE `inventory` | |||
DROP FOREIGN KEY `FK_INVENTORY_TO_UOM_ON_UOM_ID`; | |||
ALTER TABLE `inventory` | |||
CHANGE COLUMN `onHandQty` `onHandQty` DECIMAL(14,2) NOT NULL DEFAULT '0.00' , | |||
CHANGE COLUMN `price` `price` INT NULL DEFAULT 0 , | |||
CHANGE COLUMN `cpu` `cpu` DECIMAL(14,2) NULL DEFAULT '0.00' , | |||
CHANGE COLUMN `cpuUnit` `cpuUnit` VARCHAR(255) NULL DEFAULT 'HKD' , | |||
CHANGE COLUMN `cpm` `cpm` DECIMAL(14,2) NULL DEFAULT '0.00' , | |||
CHANGE COLUMN `cpmUnit` `cpmUnit` VARCHAR(255) NULL DEFAULT 'HKD' , | |||
CHANGE COLUMN `uomId` `uomId` INT NULL , | |||
CHANGE COLUMN `status` `status` VARCHAR(255) NOT NULL DEFAULT 'available' ; | |||
ALTER TABLE `inventory` | |||
ADD CONSTRAINT `FK_INVENTORY_TO_UOM_ON_UOM_ID` | |||
FOREIGN KEY (`uomId`) | |||
REFERENCES `uom_conversion` (`id`); | |||