Ver a proveniência

[bom conversion] service init

create_edit_user
jason.lam há 3 meses
ascendente
cometimento
107563881b
7 ficheiros alterados com 32209 adições e 1 eliminações
  1. +2
    -1
      build.gradle
  2. +48
    -0
      src/main/java/com/ffii/fpsms/modules/master/entity/UomConversion.kt
  3. +12
    -0
      src/main/java/com/ffii/fpsms/modules/master/entity/UomConversionRepository.kt
  4. +244
    -0
      src/main/java/com/ffii/fpsms/modules/master/service/UomConversionService.kt
  5. +32
    -0
      src/main/java/com/ffii/fpsms/modules/master/web/UomConversionController.kt
  6. +31841
    -0
      src/main/resources/dataExport/MTMS_bom_raw.json
  7. +30
    -0
      src/main/resources/db/changelog/changes/20250508_01_jason_lam/01_recreate_uom_conversion_table.sql

+ 2
- 1
build.gradle Ver ficheiro

@@ -28,7 +28,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
implementation 'org.springframework.security:spring-security-ldap'
implementation 'org.liquibase:liquibase-core'
implementation 'com.google.code.gson:gson:2.8.5'

implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'
implementation group: 'org.apache.poi', name: 'poi', version: '5.2.3'
implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '5.2.3'


+ 48
- 0
src/main/java/com/ffii/fpsms/modules/master/entity/UomConversion.kt Ver ficheiro

@@ -0,0 +1,48 @@
package com.ffii.fpsms.modules.master.entity

import com.ffii.core.entity.BaseEntity
import com.ffii.fpsms.modules.master.web.models.ItemType
import jakarta.persistence.*
import jakarta.validation.constraints.NotNull
import java.time.LocalDateTime

@Entity
@Table(name = "uom_conversion")
open class UomConversion : BaseEntity<Long>() {

@Column(name = "m18Id")
open var m18Id: Long = 0L

@Column(name = "code")
open var code: String? = null

@Column(name = "udfudesc")
open var udfudesc: String? = null

@Column(name = "unit1")
open var unit1: String? = null

@Column(name = "unit1Qty")
open var unit1Qty: Double? = null

@Column(name = "unit2")
open var unit2: String? = null

@Column(name = "unit2Qty")
open var unit2Qty: Double? = null

@Column(name = "unit3")
open var unit3: String? = null

@Column(name = "unit3Qty")
open var unit3Qty: Double? = null

@Column(name = "sizeInGram")
open var sizeInGram: Double? = null

@Column(name = "gramPerSmallestUnit")
open var gramPerSmallestUnit: Double? = null

@Column(name = "lastModifyDate")
open var lastModifyDate: LocalDateTime = LocalDateTime.now()
}

+ 12
- 0
src/main/java/com/ffii/fpsms/modules/master/entity/UomConversionRepository.kt Ver ficheiro

@@ -0,0 +1,12 @@
package com.ffii.fpsms.modules.master.entity

import com.ffii.core.support.AbstractRepository
import org.springframework.stereotype.Repository
import java.time.LocalDateTime

@Repository
interface UomConversionRepository : AbstractRepository<UomConversion, Long> {
//fun importFromM18(): ArrayList<UomConversion>;
fun findByIdAndDeletedFalse(id: Long): UomConversion;
fun findByLastModifyDateAndM18IdAndDeletedFalse(lastModifyDate: LocalDateTime, m18Id: Long): UomConversion?;
}

+ 244
- 0
src/main/java/com/ffii/fpsms/modules/master/service/UomConversionService.kt Ver ficheiro

@@ -0,0 +1,244 @@
package com.ffii.fpsms.modules.master.service

import com.ffii.core.support.AbstractBaseEntityService
import com.ffii.core.support.JdbcDao
import com.ffii.fpsms.modules.master.entity.*
import com.ffii.fpsms.modules.master.web.models.MessageResponse
import org.springframework.core.io.ClassPathResource
import org.springframework.stereotype.Service
import com.google.gson.Gson
import org.springframework.transaction.annotation.Transactional
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.sql.DriverManager.println
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.*
import java.util.regex.Pattern


@Service
open class UomConversionService(
private val jdbcDao: JdbcDao,
private val uomConversionRepository: UomConversionRepository,
): AbstractBaseEntityService<UomConversion, Long, UomConversionRepository>(jdbcDao, uomConversionRepository) {
// do mapping with projection

private val JSON_VAL_PATH = "dataExport/MTMS_bom_raw.json"

@kotlin.Throws(IOException::class)
open fun importFromM18() : ArrayList<UomConversion>{
val resource = ClassPathResource(JSON_VAL_PATH)
val templateInputStream = resource.inputStream

// Read the JSON file into a String
val jsonStringBuilder = StringBuilder()
BufferedReader(InputStreamReader(templateInputStream)).use { reader ->
var line: String?
while (reader.readLine().also { line = it } != null) {
jsonStringBuilder.append(line)
}
}
val gson = Gson()
val bomData: BomData = gson.fromJson(jsonStringBuilder.toString(), BomData::class.java)
val bomObjects = bomData.values
val output = ArrayList<UomConversion>()
for (i in bomObjects.indices) {
val transformedItem = transformItem(bomObjects[i])
output.add(transformedItem)
}
calculateSizeInGram(output)
return output;
}

open fun parseDate(dateString: String?): LocalDateTime {
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
return LocalDateTime.parse(dateString, formatter)
}

class BomData {
var stSearch: String? = null
var size = 0
lateinit var values: Array<BomObject>
}

class BomObject {
var code: String? = null
var udfudesc: String? = null
var lastModifyDate: String? = null
var id: Long? = null
override fun toString(): String {
return "YourObject{" +
"code='" + code + '\'' +
", udfudesc='" + udfudesc + '\'' +
", lastModifyDate=" + lastModifyDate + '\'' +
", id=" + id +
'}'
}
}
open fun transformItem(item: BomObject): UomConversion {
val code = if (item.code == null) "N/A" else item.code
val udfudesc = item.udfudesc
val id = item.id
val lastModifyDate = parseDate(item.lastModifyDate)
// Initialize quantities and units
var unit1Qty = 1.0
var unit2Qty = 0.0
var unit3Qty = 0.0
var unit1: String? = null
var unit2: String? = null
var unit3: String? = null
val sizeInGram = 0.0
val gramPerSmallestUnit = 0.0

// Regex to extract numbers (including decimals) and units
// Regex to extract numbers (including decimals) and units
val pattern =
Pattern.compile("(?:(\\d*\\.?\\d+)?([A-Za-z]+))?(?:(\\d*\\.?\\d+)([A-Za-z]+))?(?:(\\d*\\.?\\d+)([A-Za-z]+))?")
val matcher = pattern.matcher(code)
if (matcher.find()) {
// Capture groups
val group1 = matcher.group(1)
unit1Qty = if (group1 == null || group1.isEmpty()) 1.0 else group1.toDouble()
unit1 = if (matcher.group(2) != null) matcher.group(2) else ""
val group3 = matcher.group(3)
unit2Qty = if (group3 == null || group3.isEmpty()) 0.0 else group3.toDouble()
unit2 = if (matcher.group(4) != null) matcher.group(4) else ""
val group5 = matcher.group(5)
unit3Qty = if (group5 == null || group5.isEmpty()) 0.0 else group5.toDouble()
unit3 = if (matcher.group(6) != null) matcher.group(6) else ""
}

// Create the transformed JSON object
val transformedItem = UomConversion()
transformedItem.code = code
transformedItem.udfudesc = udfudesc
transformedItem.unit1 = unit1
transformedItem.unit1Qty = unit1Qty
transformedItem.unit2 = unit2
transformedItem.unit2Qty = unit2Qty
transformedItem.unit3 = unit3
transformedItem.unit3Qty = unit3Qty
transformedItem.sizeInGram = sizeInGram
transformedItem.gramPerSmallestUnit = gramPerSmallestUnit
if (id != null) {
transformedItem.m18Id = id
}
transformedItem.lastModifyDate = lastModifyDate
return transformedItem
}

open fun calculateSizeInGram(output: ArrayList<UomConversion>) {
// Define the conversion factors
val units: MutableMap<String, Double> = HashMap()
units.put("KG", 1000.0)
units.put("G", 1.0)
units.put("LG", 453.59)
units.put("POUNDS", 453.59)
units.put("CATTY", 604.78982)
units.put("OZ", 28.3495)
units.put("TAEL", 37.5)
for (item in output) {
var totalGram = 0.0
var smallestUnitGram = 0.0

// Calculate based on unit1
if (item.unit1 != null && item.unit1Qty != null) {
smallestUnitGram += item.unit1Qty!! // Assuming unit1 is a direct quantity
}

// Calculate based on unit2
if (item.unit2 != null && item.unit2Qty != null) {
if (units.containsKey(item.unit2!!.uppercase(Locale.getDefault()))) {
totalGram += item.unit1Qty!! * item.unit2Qty!! * units[item.unit2!!.uppercase(Locale.getDefault())]!!
smallestUnitGram = item.unit2Qty!! * units[item.unit2!!.uppercase(Locale.getDefault())]!!
}
}

// Calculate based on unit3
if (item.unit3 != null && item.unit3Qty != null) {
if (units.containsKey(item.unit3!!.uppercase(Locale.getDefault()))) {
totalGram += item.unit1Qty!! * item.unit2Qty!! * item.unit3Qty!! * units[item.unit3!!.uppercase(Locale.getDefault())]!!
smallestUnitGram = item.unit3Qty!! * units[item.unit3!!.uppercase(Locale.getDefault())]!!
}
}
if (units.containsKey(item.unit1!!.uppercase(Locale.getDefault())) ||
units.containsKey(item.unit2!!.uppercase(Locale.getDefault())) ||
units.containsKey(item.unit3!!.uppercase(Locale.getDefault()))
) {
// If any valid conversion was made, set sizeInGram and gramPerSmallestUnit
item.sizeInGram = totalGram
item.gramPerSmallestUnit = smallestUnitGram
} else {
// Set to 0 if no valid units found
item.sizeInGram = 0.0
item.gramPerSmallestUnit = 0.0
}
}
}

@Throws(IOException::class)
@Transactional
open fun saveUomConversion(newUomConversion: UomConversion): MessageResponse {
val duplicatedItem = uomConversionRepository.findByLastModifyDateAndM18IdAndDeletedFalse(newUomConversion.lastModifyDate, newUomConversion.m18Id)
if (duplicatedItem != null && duplicatedItem.id != newUomConversion.id) {
return MessageResponse(
id = newUomConversion.id,
code = newUomConversion.code,
name = newUomConversion.udfudesc,
type = "UOM update to date",
message = "BOM with M18Id = ${duplicatedItem.m18Id} is already up to date",
errorPosition = "code"
)
}

val uomConversion = if (newUomConversion.id != null && newUomConversion.id > 0)
uomConversionRepository.findByIdAndDeletedFalse(newUomConversion.id)
else UomConversion()

if (uomConversion == null) {
// Handle the case where the item does not exist
return MessageResponse(
id = null,
code = newUomConversion.code,
name = newUomConversion.udfudesc,
type = "Error",
message = "UOM conversion not found for ID: ${newUomConversion.id}",
errorPosition = "database"
)
}

uomConversion.apply {
m18Id = newUomConversion.m18Id
code = newUomConversion.code
udfudesc = newUomConversion.udfudesc
unit1 = newUomConversion.unit1
unit1Qty = newUomConversion.unit1Qty
unit2 = newUomConversion.unit2
unit2Qty = newUomConversion.unit2Qty
unit3 = newUomConversion.unit3
unit3Qty = newUomConversion.unit3Qty
sizeInGram = newUomConversion.sizeInGram
gramPerSmallestUnit = newUomConversion.gramPerSmallestUnit
lastModifyDate = newUomConversion.lastModifyDate
}

return try {
val savedItem = uomConversionRepository.saveAndFlush(uomConversion)
MessageResponse(
id = savedItem.id,
name = newUomConversion.code,
code = newUomConversion.code,
type = "M18BOM",
message = "UOM Save Success",
errorPosition = null
)
} catch (e: Exception) {
// Log the exception
throw RuntimeException("Error saving UOM conversion: ${e.message}", e)
}
}
}

+ 32
- 0
src/main/java/com/ffii/fpsms/modules/master/web/UomConversionController.kt Ver ficheiro

@@ -0,0 +1,32 @@
package com.ffii.fpsms.modules.master.web

import com.ffii.fpsms.modules.master.entity.UomConversion
import com.ffii.fpsms.modules.master.service.UomConversionService
import jakarta.servlet.http.HttpServletRequest
import org.springframework.web.bind.annotation.*
import java.util.ArrayList


@RestController
@RequestMapping("/uomConversion")
class UomConversionController(
private val uomConversionService: UomConversionService
) {
// @GetMapping
// fun allItems(): List<Items> {
// return uomConversionService.allItems()
// }

@RequestMapping(value = ["/castBom"], method = [RequestMethod.GET])
fun convertBom(request: HttpServletRequest?): ArrayList<UomConversion> {
try {
val objResult = uomConversionService.importFromM18();
for(bomRecord in objResult){
uomConversionService.saveUomConversion(bomRecord);
}
return objResult;
} catch (e: Exception) {
throw RuntimeException("Error converting BOM: ${e.message}", e)
}
}
}

+ 31841
- 0
src/main/resources/dataExport/MTMS_bom_raw.json
A apresentação das diferenças no ficheiro foi suprimida por ser demasiado grande
Ver ficheiro


+ 30
- 0
src/main/resources/db/changelog/changes/20250508_01_jason_lam/01_recreate_uom_conversion_table.sql Ver ficheiro

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

--changeset jason:update uom_conversion
DROP TABLE IF EXISTS uom_conversion;

CREATE TABLE uom_conversion
(
id INT NOT NULL AUTO_INCREMENT,
version INT NOT NULL DEFAULT '0',
created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
createdBy VARCHAR(30) NULL,
modified datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
modifiedBy VARCHAR(30) NULL,
deleted TINYINT(1) NOT NULL DEFAULT '0',

m18Id INT NOT NULL,
code VARCHAR(50) NULL,
udfudesc VARCHAR(50) NULL,
unit1 VARCHAR(50) NULL,
unit1Qty DECIMAL(16, 2) NULL DEFAULT 1,
unit2 VARCHAR(50) NULL,
unit2Qty DECIMAL(16, 2) NULL,
unit3 VARCHAR(50) NULL,
unit3Qty DECIMAL(16, 2) NULL,
sizeInGram DECIMAL(16, 2) NULL,
gramPerSmallestUnit DECIMAL(16, 2) NULL,
lastModifyDate datetime NOT NULL,

CONSTRAINT pk_uom_conversion PRIMARY KEY (id)
);

Carregando…
Cancelar
Guardar