|
@@ -90,41 +90,70 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
groupData: MutableList<MutableMap<String, Any?>>? = null
|
|
groupData: MutableList<MutableMap<String, Any?>>? = null
|
|
|
) {
|
|
) {
|
|
|
val fieldMapping = fields.mapValues { it.value.substringAfterLast(".") }
|
|
val fieldMapping = fields.mapValues { it.value.substringAfterLast(".") }
|
|
|
|
|
+ val hasParent = fieldMapping.any { it.key == "parent_id" }
|
|
|
val uniqueField = fieldMapping["code"] ?: "id"
|
|
val uniqueField = fieldMapping["code"] ?: "id"
|
|
|
val uniqueFieldId = fieldMapping["id"]
|
|
val uniqueFieldId = fieldMapping["id"]
|
|
|
|
|
|
|
|
val historyIndex = buildHistoryIndex(historyData, uniqueField, uniqueFieldId)
|
|
val historyIndex = buildHistoryIndex(historyData, uniqueField, uniqueFieldId)
|
|
|
|
|
+ val historyIndexById = buildHistoryIndex(historyData, uniqueField, uniqueFieldId, byId = true)
|
|
|
val groupIndex = buildGroupIndex(groupData, uniqueFieldId ?: uniqueField)
|
|
val groupIndex = buildGroupIndex(groupData, uniqueFieldId ?: uniqueField)
|
|
|
|
|
|
|
|
val fieldRoots = fields.filterValues { !it.contains(".") }
|
|
val fieldRoots = fields.filterValues { !it.contains(".") }
|
|
|
val joinRoots = fields.filterValues { it.contains(".") }
|
|
val joinRoots = fields.filterValues { it.contains(".") }
|
|
|
|
|
|
|
|
- val chunkData = rootData.chunked(1000)
|
|
|
|
|
- logger.info("data migration class ${clazz.simpleName} chunk data ${chunkData.size}")
|
|
|
|
|
- chunkData.forEachIndexed { _, data ->
|
|
|
|
|
- val dataMap = data.map { row ->
|
|
|
|
|
|
|
+ if (hasParent) {
|
|
|
|
|
+ val finalizeData = rootData.map { row ->
|
|
|
buildRow(
|
|
buildRow(
|
|
|
row,
|
|
row,
|
|
|
fieldRoots,
|
|
fieldRoots,
|
|
|
joinRoots,
|
|
joinRoots,
|
|
|
historyIndex,
|
|
historyIndex,
|
|
|
|
|
+ historyIndexById,
|
|
|
groupIndex,
|
|
groupIndex,
|
|
|
uniqueField,
|
|
uniqueField,
|
|
|
uniqueFieldId
|
|
uniqueFieldId
|
|
|
)
|
|
)
|
|
|
- }.map { postProcessPassword(it) }
|
|
|
|
|
- queueInsertData.put((clazz as Class<out BaseEntity>) to dataMap)
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ val chunkData = (if (finalizeData.any { it.any { a -> a.key == "structure" } }) {
|
|
|
|
|
+ finalizeData.sortedBy { f -> f["structure"].toString().length }
|
|
|
|
|
+ } else finalizeData).chunked(1000)
|
|
|
|
|
+
|
|
|
|
|
+ logger.info("data migration class ${clazz.simpleName} chunk data ${chunkData.size}")
|
|
|
|
|
+ chunkData.forEachIndexed { _, data ->
|
|
|
|
|
+ queueInsertData.put((clazz as Class<out BaseEntity>) to data)
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ val chunkData = rootData.chunked(1000)
|
|
|
|
|
+ logger.info("data migration class ${clazz.simpleName} chunk data ${chunkData.size}")
|
|
|
|
|
+ chunkData.forEachIndexed { _, data ->
|
|
|
|
|
+ val dataMap = data.map { row ->
|
|
|
|
|
+ buildRow(
|
|
|
|
|
+ row,
|
|
|
|
|
+ fieldRoots,
|
|
|
|
|
+ joinRoots,
|
|
|
|
|
+ historyIndex,
|
|
|
|
|
+ historyIndexById,
|
|
|
|
|
+ groupIndex,
|
|
|
|
|
+ uniqueField,
|
|
|
|
|
+ uniqueFieldId
|
|
|
|
|
+ )
|
|
|
|
|
+ }.map { postProcessPassword(it) }
|
|
|
|
|
+ queueInsertData.put((clazz as Class<out BaseEntity>) to dataMap)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private fun buildHistoryIndex(
|
|
private fun buildHistoryIndex(
|
|
|
historyData: List<Map<String, Any?>>?,
|
|
historyData: List<Map<String, Any?>>?,
|
|
|
uniqueField: String,
|
|
uniqueField: String,
|
|
|
- uniqueFieldId: String?
|
|
|
|
|
|
|
+ uniqueFieldId: String?,
|
|
|
|
|
+ byId: Boolean = false
|
|
|
): Map<Any?, Map<String, Any?>>? {
|
|
): Map<Any?, Map<String, Any?>>? {
|
|
|
if (historyData == null || uniqueFieldId == null) return null
|
|
if (historyData == null || uniqueFieldId == null) return null
|
|
|
return historyData
|
|
return historyData
|
|
|
- .groupBy { it[uniqueField] }
|
|
|
|
|
|
|
+ .groupBy { if (byId) it[uniqueFieldId] else it[uniqueField] }
|
|
|
.mapValues { (_, items) ->
|
|
.mapValues { (_, items) ->
|
|
|
items.maxByOrNull {
|
|
items.maxByOrNull {
|
|
|
it[uniqueFieldId.removePrefix("history.")]
|
|
it[uniqueFieldId.removePrefix("history.")]
|
|
@@ -143,6 +172,7 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
fieldRoots: Map<String, String>,
|
|
fieldRoots: Map<String, String>,
|
|
|
joinRoots: Map<String, String>,
|
|
joinRoots: Map<String, String>,
|
|
|
historyIndex: Map<Any?, Map<String, Any?>>?,
|
|
historyIndex: Map<Any?, Map<String, Any?>>?,
|
|
|
|
|
+ historyIndexById: Map<Any?, Map<String, Any?>>?,
|
|
|
groupIndex: Map<String?, Map<String, Any?>>?,
|
|
groupIndex: Map<String?, Map<String, Any?>>?,
|
|
|
uniqueField: String,
|
|
uniqueField: String,
|
|
|
uniqueFieldId: String?
|
|
uniqueFieldId: String?
|
|
@@ -152,13 +182,20 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
fieldRoots.forEach { (target, source) -> data[target] = row[source] }
|
|
fieldRoots.forEach { (target, source) -> data[target] = row[source] }
|
|
|
// Join fields
|
|
// Join fields
|
|
|
joinRoots.forEach { (target, sourceFull) ->
|
|
joinRoots.forEach { (target, sourceFull) ->
|
|
|
-
|
|
|
|
|
val value = when {
|
|
val value = when {
|
|
|
sourceFull.startsWith("history.") -> {
|
|
sourceFull.startsWith("history.") -> {
|
|
|
val key = sourceFull.removePrefix("history.")
|
|
val key = sourceFull.removePrefix("history.")
|
|
|
- historyIndex
|
|
|
|
|
|
|
+ val valueHistories = historyIndex
|
|
|
?.get(row[uniqueField])
|
|
?.get(row[uniqueField])
|
|
|
?.get(key.substringAfterLast("."))
|
|
?.get(key.substringAfterLast("."))
|
|
|
|
|
+ valueHistories?.let { valHis ->
|
|
|
|
|
+ if (target.contains("_")) {
|
|
|
|
|
+ val codeKey = uniqueField.removePrefix("history.")
|
|
|
|
|
+ val joinCode = historyIndexById?.get(valHis)?.get(codeKey)
|
|
|
|
|
+ joinCode
|
|
|
|
|
+ } else valHis
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
sourceFull.startsWith("group.") -> {
|
|
sourceFull.startsWith("group.") -> {
|
|
@@ -230,25 +267,70 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
return map
|
|
return map
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// private fun splitValues(input: String): List<String> {
|
|
|
|
|
+// val result = mutableListOf<String>()
|
|
|
|
|
+// var depth = 0
|
|
|
|
|
+// var current = StringBuilder()
|
|
|
|
|
+// for (c in input) {
|
|
|
|
|
+// when (c) {
|
|
|
|
|
+// '(' -> depth++
|
|
|
|
|
+// ')' -> depth--
|
|
|
|
|
+// ',' -> {
|
|
|
|
|
+// if (depth == 0) {
|
|
|
|
|
+// result.add(current.toString())
|
|
|
|
|
+// current = StringBuilder()
|
|
|
|
|
+// continue
|
|
|
|
|
+// }
|
|
|
|
|
+// }
|
|
|
|
|
+// }
|
|
|
|
|
+// current.append(c)
|
|
|
|
|
+// }
|
|
|
|
|
+// result.add(current.toString())
|
|
|
|
|
+// return result
|
|
|
|
|
+// }
|
|
|
|
|
+
|
|
|
private fun splitValues(input: String): List<String> {
|
|
private fun splitValues(input: String): List<String> {
|
|
|
val result = mutableListOf<String>()
|
|
val result = mutableListOf<String>()
|
|
|
var depth = 0
|
|
var depth = 0
|
|
|
|
|
+ var inQuotes = false
|
|
|
var current = StringBuilder()
|
|
var current = StringBuilder()
|
|
|
- for (c in input) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ var i = 0
|
|
|
|
|
+ while (i < input.length) {
|
|
|
|
|
+ val c = input[i]
|
|
|
when (c) {
|
|
when (c) {
|
|
|
- '(' -> depth++
|
|
|
|
|
- ')' -> depth--
|
|
|
|
|
|
|
+ '\'' -> {
|
|
|
|
|
+ // toggle flag ketika ada tanda kutip tunggal
|
|
|
|
|
+ inQuotes = !inQuotes
|
|
|
|
|
+ current.append(c)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ '(' -> {
|
|
|
|
|
+ if (!inQuotes) depth++
|
|
|
|
|
+ current.append(c)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ')' -> {
|
|
|
|
|
+ if (!inQuotes) depth--
|
|
|
|
|
+ current.append(c)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
',' -> {
|
|
',' -> {
|
|
|
- if (depth == 0) {
|
|
|
|
|
- result.add(current.toString())
|
|
|
|
|
|
|
+ // hanya split jika BUKAN sedang di dalam quotes dan depth = 0
|
|
|
|
|
+ if (!inQuotes && depth == 0) {
|
|
|
|
|
+ result.add(current.toString().trim())
|
|
|
current = StringBuilder()
|
|
current = StringBuilder()
|
|
|
- continue
|
|
|
|
|
|
|
+ } else {
|
|
|
|
|
+ current.append(c)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ else -> current.append(c)
|
|
|
}
|
|
}
|
|
|
- current.append(c)
|
|
|
|
|
|
|
+ i++
|
|
|
}
|
|
}
|
|
|
- result.add(current.toString())
|
|
|
|
|
|
|
+
|
|
|
|
|
+ result.add(current.toString().trim())
|
|
|
return result
|
|
return result
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -291,41 +373,21 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
rootData: MutableList<MutableMap<String, Any?>>,
|
|
rootData: MutableList<MutableMap<String, Any?>>,
|
|
|
historyData: MutableList<MutableMap<String, Any?>>?,
|
|
historyData: MutableList<MutableMap<String, Any?>>?,
|
|
|
groupData: MutableList<MutableMap<String, Any?>>?
|
|
groupData: MutableList<MutableMap<String, Any?>>?
|
|
|
- ) = dataToMapWithDataSource(clazz, fields, rootData, historyData, groupData)
|
|
|
|
|
-
|
|
|
|
|
- fun clazzEntity(migrationTarget: String): Class<out BaseEntity>? {
|
|
|
|
|
- return when (migrationTarget) {
|
|
|
|
|
- "organization" -> Organization::class.java
|
|
|
|
|
- "costCenter" -> CostCenter::class.java
|
|
|
|
|
- "pbx" -> Pbx::class.java
|
|
|
|
|
- "trunk" -> Trunk::class.java
|
|
|
|
|
- "callTransaction" -> Transaction::class.java
|
|
|
|
|
- "account" -> Account::class.java
|
|
|
|
|
- "area" -> Area::class.java
|
|
|
|
|
- "cdrModifier" -> CdrModifier::class.java
|
|
|
|
|
- "phoneUser" -> PhoneUser::class.java
|
|
|
|
|
- "provider" -> Provider::class.java
|
|
|
|
|
- "rate" -> Rate::class.java
|
|
|
|
|
- "webUser" -> WebUser::class.java
|
|
|
|
|
- "corcos" -> Corcos::class.java
|
|
|
|
|
- else -> null
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ) = dataToMapWithDataSource(clazz, fields, rootData, historyData, groupData)
|
|
|
|
|
|
|
|
fun <T : BaseEntity> insertData(clazz: Class<T>, dataMap: List<MutableMap<String, Any?>>): MutableList<Any> {
|
|
fun <T : BaseEntity> insertData(clazz: Class<T>, dataMap: List<MutableMap<String, Any?>>): MutableList<Any> {
|
|
|
failed.clear()
|
|
failed.clear()
|
|
|
- val sortingData = if (dataMap.any { it.any { a -> a.key == "structure" } }) {
|
|
|
|
|
- dataMap.sortedBy { f -> f["structure"].toString().length }
|
|
|
|
|
- } else dataMap
|
|
|
|
|
- sortingData.forEach { map ->
|
|
|
|
|
|
|
+ dataMap.forEach { map ->
|
|
|
try {
|
|
try {
|
|
|
val finalizer = finalizeMap(clazz.simpleName.camelCase(), map)
|
|
val finalizer = finalizeMap(clazz.simpleName.camelCase(), map)
|
|
|
val phoneUserPin = finalizer["pin"]
|
|
val phoneUserPin = finalizer["pin"]
|
|
|
val phoneUserExtension = finalizer["extension"]
|
|
val phoneUserExtension = finalizer["extension"]
|
|
|
|
|
|
|
|
// budget
|
|
// budget
|
|
|
- val budgetAnnual = (finalizer["budget.maxCost"]?.toString() ?: finalizer["budget__maxCost"]?.toString())?.toDoubleOrNull()
|
|
|
|
|
- val warningAnnual = (finalizer["budget.warnCost"]?.toString() ?: finalizer["budget__warnCost"]?.toString())?.toDoubleOrNull()
|
|
|
|
|
|
|
+ val budgetAnnual = (finalizer["budget.maxCost"]?.toString()
|
|
|
|
|
+ ?: finalizer["budget__maxCost"]?.toString())?.toDoubleOrNull()
|
|
|
|
|
+ val warningAnnual = (finalizer["budget.warnCost"]?.toString()
|
|
|
|
|
+ ?: finalizer["budget__warnCost"]?.toString())?.toDoubleOrNull()
|
|
|
val budgetMaxCost = budgetAnnual?.let { max ->
|
|
val budgetMaxCost = budgetAnnual?.let { max ->
|
|
|
List(12) { max }.joinToString(";")
|
|
List(12) { max }.joinToString(";")
|
|
|
}
|
|
}
|
|
@@ -337,7 +399,7 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
|
|
|
|
|
// phoneUserPbx
|
|
// phoneUserPbx
|
|
|
val phoneUserPbxIds: MutableList<Any> = mutableListOf()
|
|
val phoneUserPbxIds: MutableList<Any> = mutableListOf()
|
|
|
- val data = if (clazz.simpleName == "PhoneUser") {
|
|
|
|
|
|
|
+ val finalMapEntity = if (clazz.simpleName == "PhoneUser") {
|
|
|
(finalizer["pbx.list"]?.toString() ?: finalizer["pbx__list"]?.toString())?.let {
|
|
(finalizer["pbx.list"]?.toString() ?: finalizer["pbx__list"]?.toString())?.let {
|
|
|
it.split(";").forEach { fi ->
|
|
it.split(";").forEach { fi ->
|
|
|
findUidByCode(Pbx::class.java, fi)?.let { id -> phoneUserPbxIds.add(id) }
|
|
findUidByCode(Pbx::class.java, fi)?.let { id -> phoneUserPbxIds.add(id) }
|
|
@@ -371,28 +433,28 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
if (phoneUserPbxIds.isEmpty()) {
|
|
if (phoneUserPbxIds.isEmpty()) {
|
|
|
finalMap["expiredDate"] = finalMap["expiredDate"] ?: LocalDate.now().atStartOfDay()
|
|
finalMap["expiredDate"] = finalMap["expiredDate"] ?: LocalDate.now().atStartOfDay()
|
|
|
}
|
|
}
|
|
|
- queryNativeService.insertDataWithNativeQuery(clazz, finalMap)
|
|
|
|
|
- } else {
|
|
|
|
|
- queryNativeService.insertDataWithNativeQuery(clazz, finalizer)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // create budget
|
|
|
|
|
- if (BudgetUserType.entries.any { a -> a.name.snakeToCamel() == clazz.simpleName.camelCase() }) {
|
|
|
|
|
- queryNativeService.insertDataWithNativeQuery(
|
|
|
|
|
- Budget::class.java, mutableMapOf(
|
|
|
|
|
- "userType" to BudgetUserType.valueOf(
|
|
|
|
|
- clazz.simpleName.camelCase().camelToSnake().uppercase()
|
|
|
|
|
- ).ordinal,
|
|
|
|
|
- "userUid" to data,
|
|
|
|
|
- "type" to BudgetType.FLAT.ordinal,
|
|
|
|
|
- "annualCost" to (budgetAnnual?.let { it * 12 }?.toInt() ?: 0),
|
|
|
|
|
- "accumulate" to 0,
|
|
|
|
|
- "maxCost" to (budgetMaxCost ?: "0;0;0;0;0;0;0;0;0;0;0;0"),
|
|
|
|
|
- "warnCostPercentage" to (budgetWarnCost ?: "0;0;0;0;0;0;0;0;0;0;0;0"),
|
|
|
|
|
- "tempCost" to "0;0;0;0;0;0;0;0;0;0;0;0",
|
|
|
|
|
- "maxAutoCalculate" to "1;1;1;1;1;1;1;1;1;1;1;1"
|
|
|
|
|
|
|
+ finalMap
|
|
|
|
|
+ } else finalizer
|
|
|
|
|
+
|
|
|
|
|
+ queryNativeService.insertDataWithNativeQuery(clazz, finalMapEntity, functionAfter = { uid ->
|
|
|
|
|
+ // create budget
|
|
|
|
|
+ if (BudgetUserType.entries.any { a -> a.name.snakeToCamel() == clazz.simpleName.camelCase() }) {
|
|
|
|
|
+ queryNativeService.insertDataWithNativeQuery(
|
|
|
|
|
+ Budget::class.java, mutableMapOf(
|
|
|
|
|
+ "userType" to BudgetUserType.valueOf(
|
|
|
|
|
+ clazz.simpleName.camelCase().camelToSnake().uppercase()
|
|
|
|
|
+ ).ordinal,
|
|
|
|
|
+ "userUid" to uid,
|
|
|
|
|
+ "type" to BudgetType.FLAT.ordinal,
|
|
|
|
|
+ "annualCost" to (budgetAnnual?.let { it * 12 }?.toInt() ?: 0),
|
|
|
|
|
+ "accumulate" to 0,
|
|
|
|
|
+ "maxCost" to (budgetMaxCost ?: "0;0;0;0;0;0;0;0;0;0;0;0"),
|
|
|
|
|
+ "warnCostPercentage" to (budgetWarnCost ?: "0;0;0;0;0;0;0;0;0;0;0;0"),
|
|
|
|
|
+ "tempCost" to "0;0;0;0;0;0;0;0;0;0;0;0",
|
|
|
|
|
+ "maxAutoCalculate" to "1;1;1;1;1;1;1;1;1;1;1;1"
|
|
|
|
|
+ )
|
|
|
)
|
|
)
|
|
|
- )
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// create phoneUserPbx
|
|
// create phoneUserPbx
|
|
|
if (phoneUserPbxIds.isNotEmpty()) {
|
|
if (phoneUserPbxIds.isNotEmpty()) {
|
|
@@ -402,12 +464,12 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
"pin" to phoneUserPin,
|
|
"pin" to phoneUserPin,
|
|
|
"extension" to phoneUserExtension,
|
|
"extension" to phoneUserExtension,
|
|
|
"pbx_id" to pbxId,
|
|
"pbx_id" to pbxId,
|
|
|
- "phoneUser_id" to data,
|
|
|
|
|
|
|
+ "phoneUser_id" to uid,
|
|
|
)
|
|
)
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
+ })
|
|
|
} catch (e: Exception) {
|
|
} catch (e: Exception) {
|
|
|
failed.add(map)
|
|
failed.add(map)
|
|
|
logger.error("failed insert data migration", e)
|
|
logger.error("failed insert data migration", e)
|
|
@@ -460,7 +522,7 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
val value = if (t == "pbx_id") {
|
|
val value = if (t == "pbx_id") {
|
|
|
findUidByCode(Pbx::class.java, u ?: "PBX01")
|
|
findUidByCode(Pbx::class.java, u ?: "PBX01")
|
|
|
} else u?.toString()?.let { code ->
|
|
} else u?.toString()?.let { code ->
|
|
|
- val clazzEntity = clazzEntity(if (isParent) className else t.split("_")[0])
|
|
|
|
|
|
|
+ val clazzEntity = General.clazzEntity(if (isParent) className else t.split("_")[0])
|
|
|
clazzEntity?.let { findUidByCode(it, code) }
|
|
clazzEntity?.let { findUidByCode(it, code) }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -559,28 +621,34 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private fun <T : BaseEntity> findUidByCode(clazz: Class<T>, value: Any): String? {
|
|
private fun <T : BaseEntity> findUidByCode(clazz: Class<T>, value: Any): String? {
|
|
|
- return tempDataParent["${clazz.simpleName}_$value"] ?: run {
|
|
|
|
|
- val tmpData = temporaryData[clazz.simpleName] ?: run {
|
|
|
|
|
- val data = apiService.findListAll(clazz)
|
|
|
|
|
- .associateBy { it["code"]?.toString() ?: it["id"]!!.toString() }
|
|
|
|
|
- temporaryData[clazz.simpleName] = data
|
|
|
|
|
- data
|
|
|
|
|
|
|
+ return temporaryDataByCode["${clazz.simpleName};$value"] ?: run {
|
|
|
|
|
+ val uid = temporaryDataEntity["${clazz.simpleName};$value"]?.get("uid") ?: run {
|
|
|
|
|
+ apiService.findListPage(
|
|
|
|
|
+ clazz, filter = FilterData.filter("code", FilterData.FILTEROP.EQ, "$value")
|
|
|
|
|
+ ).firstOrNull()?.let { data ->
|
|
|
|
|
+ temporaryDataEntity["${clazz.simpleName};$value"] = data
|
|
|
|
|
+ temporaryDataByCode["${clazz.simpleName};$value"] = data["uid"].toString()
|
|
|
|
|
+ data["uid"].toString()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- tmpData[value.toString()]?.get("uid")?.toString()
|
|
|
|
|
|
|
+ uid?.toString()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private fun findPinPhonePbx(phoneUserCode: String): Pair<String, String>? {
|
|
private fun findPinPhonePbx(phoneUserCode: String): Pair<String, String>? {
|
|
|
- val tmpData = temporaryData[PhoneUserPbx::class.java.simpleName] ?: run {
|
|
|
|
|
- val data = apiService.findListAll(
|
|
|
|
|
|
|
+ val key = "${PhoneUserPbx::class.java.simpleName};$phoneUserCode"
|
|
|
|
|
+ val tmpData = temporaryDataEntity[key] ?: run {
|
|
|
|
|
+ apiService.findListAll(
|
|
|
PhoneUserPbx::class.java,
|
|
PhoneUserPbx::class.java,
|
|
|
listOf("pin", "pbx.uid", "phoneUser.code")
|
|
listOf("pin", "pbx.uid", "phoneUser.code")
|
|
|
- ).associateBy { it["phoneUser.code"]!!.toString() }
|
|
|
|
|
- temporaryData[PhoneUserPbx::class.java.simpleName] = data
|
|
|
|
|
- data
|
|
|
|
|
|
|
+ ).forEach { dt ->
|
|
|
|
|
+ temporaryDataEntity["${PhoneUserPbx::class.java.simpleName};${dt["phoneUser.code"]!!.toString()}"] = dt
|
|
|
|
|
+ }
|
|
|
|
|
+ //.associateBy { it["phoneUser.code"]!!.toString() }
|
|
|
|
|
+ temporaryDataEntity[key]
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return tmpData[phoneUserCode]?.let { it["pbx.uid"].toString() to it["pin"].toString() }
|
|
|
|
|
|
|
+ return tmpData?.let { it["pbx.uid"].toString() to it["pin"].toString() }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
@@ -628,11 +696,26 @@ class SecurityConfig {
|
|
|
|
|
|
|
|
@Service
|
|
@Service
|
|
|
@Transactional
|
|
@Transactional
|
|
|
-class QueryNativeService(val apiService: ApiService) {
|
|
|
|
|
|
|
+class QueryNativeService(
|
|
|
|
|
+ val apiService: ApiService,
|
|
|
|
|
+ val migrationSettingService: MigrationSettingService
|
|
|
|
|
+) {
|
|
|
|
|
+
|
|
|
|
|
+ fun <T> insertDataWithNativeQuery(
|
|
|
|
|
+ clazz: Class<T>,
|
|
|
|
|
+ mapData: MutableMap<String, Any?>,
|
|
|
|
|
+ functionAfter: ((uid: String) -> Unit)? = null
|
|
|
|
|
+ ): String? {
|
|
|
|
|
+
|
|
|
|
|
+ val fieldUnique = migrationSettingService.schema.firstOrNull {
|
|
|
|
|
+ it.table.equals(clazz.simpleName, ignoreCase = true)
|
|
|
|
|
+ }?.unique
|
|
|
|
|
+ val fieldKey = fieldUnique?.split(";")?.mapNotNull { m -> mapData[m]?.toString() }?.joinToString(";")
|
|
|
|
|
+
|
|
|
|
|
+ val uidFromDb = temporaryDataEntity["${clazz.simpleName};$fieldKey"]?.get("uid")?.toString()
|
|
|
|
|
+ val uid = uidFromDb ?: ULID.random()
|
|
|
|
|
+ val isUpdate = uidFromDb != null
|
|
|
|
|
|
|
|
- fun <T> insertDataWithNativeQuery(clazz: Class<T>, mapData: MutableMap<String, Any?>): String? {
|
|
|
|
|
- val uid = ULID.random()
|
|
|
|
|
- val cpId = mapData["cpid"]
|
|
|
|
|
val fields = mutableListOf("uid")
|
|
val fields = mutableListOf("uid")
|
|
|
val finalMap = mapData.filterNot { it.key == "cpid" }
|
|
val finalMap = mapData.filterNot { it.key == "cpid" }
|
|
|
finalMap.keys.forEach {
|
|
finalMap.keys.forEach {
|
|
@@ -641,7 +724,10 @@ class QueryNativeService(val apiService: ApiService) {
|
|
|
}
|
|
}
|
|
|
val structure = finalMap["parent_id"]?.toString()?.let {
|
|
val structure = finalMap["parent_id"]?.toString()?.let {
|
|
|
fields.add("structure")
|
|
fields.add("structure")
|
|
|
- "${EntityUtility(apiService, Organization::class.java).parentStructure(it)}|$uid"
|
|
|
|
|
|
|
+ val parentUid = EntityUtility(
|
|
|
|
|
+ apiService, General.clazzEntity(clazz.simpleName.camelCase())!!
|
|
|
|
|
+ ).parentStructure(it)
|
|
|
|
|
+ "$parentUid|$uid"
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
val tableName = when (clazz.simpleName.lowercase()) {
|
|
val tableName = when (clazz.simpleName.lowercase()) {
|
|
@@ -654,28 +740,38 @@ class QueryNativeService(val apiService: ApiService) {
|
|
|
else -> clazz.simpleName.camelToSnake().lowercase()
|
|
else -> clazz.simpleName.camelToSnake().lowercase()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- val tempField = fields.joinToString() { it.camelToSnake() }
|
|
|
|
|
-
|
|
|
|
|
- val query = "INSERT INTO $tableName ($tempField) " +
|
|
|
|
|
- "VALUES (${fields.joinToString() { ":$it" }})"
|
|
|
|
|
|
|
+ val query = fieldUnique?.let { fu ->
|
|
|
|
|
+ val uniqueOn = fu.split(";").joinToString(" AND ") { m -> "t.$m = s.$m" }
|
|
|
|
|
+ """
|
|
|
|
|
+ MERGE INTO $tableName AS t
|
|
|
|
|
+ USING (VALUES (${fields.joinToString() { ":$it" }}))
|
|
|
|
|
+ AS s(${fields.joinToString() { it.camelToSnake() }})
|
|
|
|
|
+ ON $uniqueOn
|
|
|
|
|
+ WHEN MATCHED THEN
|
|
|
|
|
+ UPDATE SET
|
|
|
|
|
+ ${fields.joinToString(",\n") { "t.${it.camelToSnake()} = s.${it.camelToSnake()}" }}
|
|
|
|
|
+ WHEN NOT MATCHED THEN
|
|
|
|
|
+ INSERT (${fields.joinToString { it.camelToSnake() }})
|
|
|
|
|
+ VALUES (${fields.joinToString { "s.${it.camelToSnake()}" }});
|
|
|
|
|
+""".trimIndent()
|
|
|
|
|
+ } ?: ("INSERT INTO $tableName (${fields.joinToString() { it.camelToSnake() }}) " +
|
|
|
|
|
+ "VALUES (${fields.joinToString() { ":$it" }})")
|
|
|
|
|
+
|
|
|
|
|
+// val tempField = fields.joinToString() { it.camelToSnake() }
|
|
|
|
|
+// val query = "INSERT INTO $tableName ($tempField) " +
|
|
|
|
|
+// "VALUES (${fields.joinToString() { ":$it" }})"
|
|
|
|
|
|
|
|
val sqlNative = apiService.em.createNativeQuery(query)
|
|
val sqlNative = apiService.em.createNativeQuery(query)
|
|
|
|
|
|
|
|
if (clazz.simpleName.lowercase() != "transaction") {
|
|
if (clazz.simpleName.lowercase() != "transaction") {
|
|
|
sqlNative.setParameter("uid", uid)
|
|
sqlNative.setParameter("uid", uid)
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
structure?.let { sqlNative.setParameter("structure", structure) }
|
|
structure?.let { sqlNative.setParameter("structure", structure) }
|
|
|
finalMap.forEach { (t, u) -> sqlNative.setParameter(t.replace("_id", "_uid"), u) }
|
|
finalMap.forEach { (t, u) -> sqlNative.setParameter(t.replace("_id", "_uid"), u) }
|
|
|
sqlNative.executeUpdate()
|
|
sqlNative.executeUpdate()
|
|
|
|
|
|
|
|
- if (clazz.simpleName.lowercase() == "organization" || clazz.simpleName.lowercase() == "costcenter") {
|
|
|
|
|
- finalMap["code"]?.let {
|
|
|
|
|
- tempDataParent["${clazz.simpleName}_$it"] = uid
|
|
|
|
|
- }
|
|
|
|
|
- cpId?.let {
|
|
|
|
|
- tempDataParent["${clazz.simpleName}_$it"] = uid
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (isUpdate) {
|
|
|
|
|
+ functionAfter?.invoke(uid)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return uid
|
|
return uid
|