|
@@ -1,3 +1,5 @@
|
|
|
|
|
+@file:Suppress("UNCHECKED_CAST")
|
|
|
|
|
+
|
|
|
package com.datacomsolusindo.migration
|
|
package com.datacomsolusindo.migration
|
|
|
|
|
|
|
|
import com.datacomsolusindo.cpx_shared_code.entity.Account
|
|
import com.datacomsolusindo.cpx_shared_code.entity.Account
|
|
@@ -48,195 +50,16 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
|
|
|
|
|
private val logger = SimpleLogger.getLogger(this::class.java)
|
|
private val logger = SimpleLogger.getLogger(this::class.java)
|
|
|
|
|
|
|
|
-// fun <T> dataToMap(
|
|
|
|
|
-// clazz: Class<T>,
|
|
|
|
|
-// fields: Map<String, String>,
|
|
|
|
|
-// unique: String,
|
|
|
|
|
-// rootFile: File,
|
|
|
|
|
-// historyFile: File? = null,
|
|
|
|
|
-// groupFile: File? = null
|
|
|
|
|
-// ): List<MutableMap<String, Any?>> {
|
|
|
|
|
-// logger.info("prepare data migration class ${clazz.simpleName}")
|
|
|
|
|
-// val process = measureTimedValue {
|
|
|
|
|
-// val historyData = historyFile?.let { readQueryDataToMap(it) }
|
|
|
|
|
-// val groupData = groupFile?.let { readQueryDataToMap(it) }
|
|
|
|
|
-// val rootData = readQueryDataToMap(rootFile)
|
|
|
|
|
-// val mapRootData = rootData.mapIndexed { index, map ->
|
|
|
|
|
-// val data: MutableMap<String, Any?> = mutableMapOf()
|
|
|
|
|
-// val fieldRoots = fields.toList().filterNot { f -> f.second.contains(".") }
|
|
|
|
|
-// val joinRoots = fields.toList().filter { f -> f.second.contains(".") }
|
|
|
|
|
-//
|
|
|
|
|
-// fieldRoots.forEach { f ->
|
|
|
|
|
-// data[f.first] = map[f.second]
|
|
|
|
|
-// }
|
|
|
|
|
-// joinRoots.sortedByDescending { it.second }.forEach { f ->
|
|
|
|
|
-// data[f.first] = when {
|
|
|
|
|
-// f.second.startsWith("history.") ->
|
|
|
|
|
-// getValueAnotherFile(fields, historyData, unique, data, f.first, f.second, "history")
|
|
|
|
|
-//
|
|
|
|
|
-// f.second.toString().startsWith("group.") ->
|
|
|
|
|
-// getValueAnotherFile(fields, groupData, unique, data, f.first, f.second, "group")
|
|
|
|
|
-//
|
|
|
|
|
-// else -> map[f.second]
|
|
|
|
|
-// }
|
|
|
|
|
-// }
|
|
|
|
|
-// data
|
|
|
|
|
-// }
|
|
|
|
|
-// mapRootData
|
|
|
|
|
-// }
|
|
|
|
|
-// logger.info("finish prepare data [${process.value.size}] migration class ${clazz.simpleName} takes time ${process.duration.inWholeMilliseconds}ms")
|
|
|
|
|
-// return process.value
|
|
|
|
|
-// }
|
|
|
|
|
-//
|
|
|
|
|
-// private fun getValueAnotherFile(
|
|
|
|
|
-// fields: Map<String, String>,
|
|
|
|
|
-// dataFile: List<Map<String, Any?>>?,
|
|
|
|
|
-// unique: String,
|
|
|
|
|
-// rootData: Map<String, Any?>,
|
|
|
|
|
-// keyRoot: String,
|
|
|
|
|
-// valRoot: String,
|
|
|
|
|
-// key: String
|
|
|
|
|
-// ): Any? {
|
|
|
|
|
-// val uniqueField = dataFile?.firstOrNull()?.let {
|
|
|
|
|
-// if (it.any { a -> a.key == fields[unique] }) unique else "id"
|
|
|
|
|
-// } ?: "id"
|
|
|
|
|
-// val fieldUnique = fields[uniqueField]!!.split(".").last()
|
|
|
|
|
-//
|
|
|
|
|
-// val value = dataFile?.firstOrNull { f ->
|
|
|
|
|
-// f[fieldUnique].toString() == rootData[uniqueField].toString()
|
|
|
|
|
-// }?.get(valRoot.replace("${key}.", ""))
|
|
|
|
|
-//
|
|
|
|
|
-// return if (keyRoot.contains("_")) value?.let { id ->
|
|
|
|
|
-// dataFile.firstOrNull { f ->
|
|
|
|
|
-// f[fields["id"]!!.split(".").last()].toString() == id.toString()
|
|
|
|
|
-// }?.get(fields["code"]) ?: value
|
|
|
|
|
-// } else value
|
|
|
|
|
-// }
|
|
|
|
|
-//
|
|
|
|
|
-// private fun readQueryDataToMap(file: File): List<Map<String, Any?>> {
|
|
|
|
|
-// val map = measureTimedValue {
|
|
|
|
|
-// file.bufferedReader(StandardCharsets.UTF_8)
|
|
|
|
|
-// .readLines().filter {
|
|
|
|
|
-// it.startsWith("INSERT")
|
|
|
|
|
-// }.mapNotNull {
|
|
|
|
|
-// try {
|
|
|
|
|
-// insertSqlToMap(it)
|
|
|
|
|
-// } catch (_: Exception) {
|
|
|
|
|
-// null
|
|
|
|
|
-// }
|
|
|
|
|
-// }
|
|
|
|
|
-// }
|
|
|
|
|
-// logger.info("migration read query data ${map.value.size} takes time ${map.duration.inWholeMilliseconds}")
|
|
|
|
|
-// return map.value
|
|
|
|
|
-// }
|
|
|
|
|
-
|
|
|
|
|
-// fun <T> dataToMap(
|
|
|
|
|
-// clazz: Class<T>,
|
|
|
|
|
-// fields: Map<String, String>,
|
|
|
|
|
-// unique: String,
|
|
|
|
|
-// rootFile: File,
|
|
|
|
|
-// historyFile: File? = null,
|
|
|
|
|
-// groupFile: File? = null
|
|
|
|
|
-// ): List<MutableMap<String, Any?>> {
|
|
|
|
|
-//
|
|
|
|
|
-// logger.info("prepare data migration class ${clazz.simpleName}")
|
|
|
|
|
-//
|
|
|
|
|
-// val process = measureTimedValue {
|
|
|
|
|
-//
|
|
|
|
|
-// // --- Read Files ---
|
|
|
|
|
-// val historyData = historyFile?.let { readQueryDataToMap(it) }
|
|
|
|
|
-// val groupData = groupFile?.let { readQueryDataToMap(it) }
|
|
|
|
|
-// val rootData = readQueryDataToMap(rootFile)
|
|
|
|
|
-//
|
|
|
|
|
-// // --- Pre-calc field names (avoid split(".") repeatedly) ---
|
|
|
|
|
-// val fieldMapping = fields.mapValues { it.value.substringAfterLast(".") }
|
|
|
|
|
-// val uniqueField = fieldMapping[unique] ?: "id"
|
|
|
|
|
-// val uniqueFieldId = fieldMapping["id"]
|
|
|
|
|
-//
|
|
|
|
|
-// // --- Create Indexes (O(n)) ---
|
|
|
|
|
-// val historyIndex = historyData?.groupBy { it[uniqueField] }?.mapValues { (_, items) ->
|
|
|
|
|
-// items.maxByOrNull {
|
|
|
|
|
-// it[uniqueFieldId!!.removePrefix("history.")].toString().toInt()
|
|
|
|
|
-// }
|
|
|
|
|
-// }
|
|
|
|
|
-// //?.associateBy { it[uniqueField]?.toString() }
|
|
|
|
|
-// val groupIndex = groupData?.associateBy { it[uniqueFieldId ?: uniqueField]?.toString() }
|
|
|
|
|
-//
|
|
|
|
|
-// val fieldRoots = fields.filter { !it.value.contains(".") }
|
|
|
|
|
-// val joinRoots = fields.filter { it.value.contains(".") }
|
|
|
|
|
-// .toList().sortedByDescending { it.second }.toMap()
|
|
|
|
|
-//
|
|
|
|
|
-// rootData.mapIndexed { index, row ->
|
|
|
|
|
-// val data = mutableMapOf<String, Any?>()
|
|
|
|
|
-//
|
|
|
|
|
-// // --- Direct Fields ---
|
|
|
|
|
-// fieldRoots.forEach { (targetKey, sourceKey) ->
|
|
|
|
|
-// data[targetKey] = row[sourceKey]
|
|
|
|
|
-// }
|
|
|
|
|
-//
|
|
|
|
|
-// // --- Join Fields ---
|
|
|
|
|
-// joinRoots.forEach { (targetKey, sourceKeyFull) ->
|
|
|
|
|
-//
|
|
|
|
|
-// val value = when {
|
|
|
|
|
-// sourceKeyFull.startsWith("history.") -> {
|
|
|
|
|
-// val sourceKey = sourceKeyFull.removePrefix("history.")
|
|
|
|
|
-// historyIndex
|
|
|
|
|
-// ?.get(row[uniqueField]?.toString())
|
|
|
|
|
-// ?.get(sourceKey.substringAfterLast("."))
|
|
|
|
|
-// }
|
|
|
|
|
-//
|
|
|
|
|
-// sourceKeyFull.startsWith("group.") -> {
|
|
|
|
|
-// val sourceKey = sourceKeyFull.removePrefix("group.")
|
|
|
|
|
-// val idKey = historyIndex
|
|
|
|
|
-// ?.get(row[uniqueField]?.toString())
|
|
|
|
|
-// ?.get(uniqueFieldId) ?: row[uniqueFieldId]
|
|
|
|
|
-// groupIndex
|
|
|
|
|
-// ?.get(idKey.toString())
|
|
|
|
|
-// ?.get(sourceKey.substringAfterLast("."))
|
|
|
|
|
-// }
|
|
|
|
|
-//
|
|
|
|
|
-// else -> row[sourceKeyFull]
|
|
|
|
|
-// }
|
|
|
|
|
-//
|
|
|
|
|
-// data[targetKey] = value
|
|
|
|
|
-// }
|
|
|
|
|
-// data
|
|
|
|
|
-// }
|
|
|
|
|
-// }
|
|
|
|
|
-//
|
|
|
|
|
-// val value = process.value.map { m ->
|
|
|
|
|
-// val dt = m as MutableMap<String, Any?>
|
|
|
|
|
-// dt["password"]?.toString()?.let {
|
|
|
|
|
-// dt["password"] = if (it.isBlank()) ""
|
|
|
|
|
-// else cpDecrypt.decrypt(it)?.let { p ->
|
|
|
|
|
-// tempPassword[p] ?: run {
|
|
|
|
|
-// val pass = passwordEncoder.encode(p)
|
|
|
|
|
-// tempPassword[p] = pass
|
|
|
|
|
-// pass
|
|
|
|
|
-// }
|
|
|
|
|
-// } ?: ""
|
|
|
|
|
-// }
|
|
|
|
|
-// dt
|
|
|
|
|
-// }
|
|
|
|
|
-// logger.info(
|
|
|
|
|
-// "finish prepare data [${process.value.size}] migration class ${clazz.simpleName} " +
|
|
|
|
|
-// "takes time ${process.duration.inWholeMilliseconds}ms"
|
|
|
|
|
-// )
|
|
|
|
|
-// return value
|
|
|
|
|
-// }
|
|
|
|
|
-
|
|
|
|
|
private fun <T> dataToMap(
|
|
private fun <T> dataToMap(
|
|
|
clazz: Class<T>,
|
|
clazz: Class<T>,
|
|
|
fields: Map<String, String>,
|
|
fields: Map<String, String>,
|
|
|
- unique: String,
|
|
|
|
|
rootFile: File,
|
|
rootFile: File,
|
|
|
historyFile: File? = null,
|
|
historyFile: File? = null,
|
|
|
groupFile: File? = null
|
|
groupFile: File? = null
|
|
|
- ): List<MutableMap<String, Any?>> {
|
|
|
|
|
- return processData(
|
|
|
|
|
|
|
+ ) {
|
|
|
|
|
+ processData(
|
|
|
clazz,
|
|
clazz,
|
|
|
fields,
|
|
fields,
|
|
|
- unique,
|
|
|
|
|
rootData = readQueryDataToMap(rootFile) as MutableList<MutableMap<String, Any?>>,
|
|
rootData = readQueryDataToMap(rootFile) as MutableList<MutableMap<String, Any?>>,
|
|
|
historyData = historyFile?.let { readQueryDataToMap(it) as MutableList<MutableMap<String, Any?>> },
|
|
historyData = historyFile?.let { readQueryDataToMap(it) as MutableList<MutableMap<String, Any?>> },
|
|
|
groupData = groupFile?.let { readQueryDataToMap(it) as MutableList<MutableMap<String, Any?>> }
|
|
groupData = groupFile?.let { readQueryDataToMap(it) as MutableList<MutableMap<String, Any?>> }
|
|
@@ -246,15 +69,13 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
private fun <T> dataToMapWithDataSource(
|
|
private fun <T> dataToMapWithDataSource(
|
|
|
clazz: Class<T>,
|
|
clazz: Class<T>,
|
|
|
fields: Map<String, String>,
|
|
fields: Map<String, String>,
|
|
|
- unique: String,
|
|
|
|
|
rootData: MutableList<MutableMap<String, Any?>>,
|
|
rootData: MutableList<MutableMap<String, Any?>>,
|
|
|
historyData: MutableList<MutableMap<String, Any?>>? = null,
|
|
historyData: MutableList<MutableMap<String, Any?>>? = null,
|
|
|
groupData: MutableList<MutableMap<String, Any?>>? = null
|
|
groupData: MutableList<MutableMap<String, Any?>>? = null
|
|
|
- ): List<MutableMap<String, Any?>> {
|
|
|
|
|
- return processData(
|
|
|
|
|
|
|
+ ) {
|
|
|
|
|
+ processData(
|
|
|
clazz,
|
|
clazz,
|
|
|
fields,
|
|
fields,
|
|
|
- unique,
|
|
|
|
|
rootData,
|
|
rootData,
|
|
|
historyData,
|
|
historyData,
|
|
|
groupData
|
|
groupData
|
|
@@ -264,26 +85,24 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
private fun <T> processData(
|
|
private fun <T> processData(
|
|
|
clazz: Class<T>,
|
|
clazz: Class<T>,
|
|
|
fields: Map<String, String>,
|
|
fields: Map<String, String>,
|
|
|
- unique: String,
|
|
|
|
|
rootData: MutableList<MutableMap<String, Any?>>,
|
|
rootData: MutableList<MutableMap<String, Any?>>,
|
|
|
historyData: MutableList<MutableMap<String, Any?>>? = null,
|
|
historyData: MutableList<MutableMap<String, Any?>>? = null,
|
|
|
groupData: MutableList<MutableMap<String, Any?>>? = null
|
|
groupData: MutableList<MutableMap<String, Any?>>? = null
|
|
|
- ): List<MutableMap<String, Any?>> {
|
|
|
|
|
-
|
|
|
|
|
- logger.info("prepare data migration class ${clazz.simpleName}")
|
|
|
|
|
-
|
|
|
|
|
- val process = measureTimedValue {
|
|
|
|
|
- val fieldMapping = fields.mapValues { it.value.substringAfterLast(".") }
|
|
|
|
|
- val uniqueField = fieldMapping[unique] ?: "id"
|
|
|
|
|
- val uniqueFieldId = fieldMapping["id"]
|
|
|
|
|
|
|
+ ) {
|
|
|
|
|
+ val fieldMapping = fields.mapValues { it.value.substringAfterLast(".") }
|
|
|
|
|
+ val uniqueField = fieldMapping["code"] ?: "id"
|
|
|
|
|
+ val uniqueFieldId = fieldMapping["id"]
|
|
|
|
|
|
|
|
- val historyIndex = buildHistoryIndex(historyData, uniqueField, uniqueFieldId)
|
|
|
|
|
- val groupIndex = buildGroupIndex(groupData, uniqueFieldId ?: uniqueField)
|
|
|
|
|
|
|
+ val historyIndex = buildHistoryIndex(historyData, uniqueField, uniqueFieldId)
|
|
|
|
|
+ val groupIndex = buildGroupIndex(groupData, uniqueFieldId ?: uniqueField)
|
|
|
|
|
|
|
|
- val fieldRoots = fields.filterValues { !it.contains(".") }
|
|
|
|
|
- val joinRoots = fields.filterValues { it.contains(".") }
|
|
|
|
|
|
|
+ val fieldRoots = fields.filterValues { !it.contains(".") }
|
|
|
|
|
+ val joinRoots = fields.filterValues { it.contains(".") }
|
|
|
|
|
|
|
|
- rootData.map { row ->
|
|
|
|
|
|
|
+ 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(
|
|
buildRow(
|
|
|
row,
|
|
row,
|
|
|
fieldRoots,
|
|
fieldRoots,
|
|
@@ -293,15 +112,9 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
uniqueField,
|
|
uniqueField,
|
|
|
uniqueFieldId
|
|
uniqueFieldId
|
|
|
)
|
|
)
|
|
|
- }
|
|
|
|
|
|
|
+ }.map { postProcessPassword(it) }
|
|
|
|
|
+ queueInsertData.put((clazz as Class<out BaseEntity>) to dataMap)
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- logger.info(
|
|
|
|
|
- "finish prepare data [${process.value.size}] migration class ${clazz.simpleName} " +
|
|
|
|
|
- "takes time ${process.duration.inWholeMilliseconds}ms"
|
|
|
|
|
- )
|
|
|
|
|
-
|
|
|
|
|
- return process.value.map { postProcessPassword(it) }
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private fun buildHistoryIndex(
|
|
private fun buildHistoryIndex(
|
|
@@ -358,6 +171,7 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
?.get(idKey?.toString())
|
|
?.get(idKey?.toString())
|
|
|
?.get(key.substringAfterLast("."))
|
|
?.get(key.substringAfterLast("."))
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
else -> row[sourceFull]
|
|
else -> row[sourceFull]
|
|
|
}
|
|
}
|
|
|
data[target] = value
|
|
data[target] = value
|
|
@@ -469,10 +283,7 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
rootFile: File,
|
|
rootFile: File,
|
|
|
historyFile: File?,
|
|
historyFile: File?,
|
|
|
groupFile: File?
|
|
groupFile: File?
|
|
|
- ): List<MutableMap<String, Any?>> {
|
|
|
|
|
- val data = dataToMap(clazz, fields, "code", rootFile, historyFile, groupFile)
|
|
|
|
|
- return data
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ) = dataToMap(clazz, fields, rootFile, historyFile, groupFile)
|
|
|
|
|
|
|
|
fun <T : BaseEntity> executeWithDataSource(
|
|
fun <T : BaseEntity> executeWithDataSource(
|
|
|
clazz: Class<T>,
|
|
clazz: Class<T>,
|
|
@@ -480,10 +291,7 @@ 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?>>?
|
|
|
- ): List<MutableMap<String, Any?>> {
|
|
|
|
|
- val data = dataToMapWithDataSource(clazz, fields, "code", rootData, historyData, groupData)
|
|
|
|
|
- return data
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ) = dataToMapWithDataSource(clazz, fields, rootData, historyData, groupData)
|
|
|
|
|
|
|
|
fun clazzEntity(migrationTarget: String): Class<out BaseEntity>? {
|
|
fun clazzEntity(migrationTarget: String): Class<out BaseEntity>? {
|
|
|
return when (migrationTarget) {
|
|
return when (migrationTarget) {
|
|
@@ -516,8 +324,8 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
val phoneUserExtension = finalizer["extension"]
|
|
val phoneUserExtension = finalizer["extension"]
|
|
|
|
|
|
|
|
// budget
|
|
// budget
|
|
|
- val budgetAnnual = finalizer["budget.maxCost"]?.toString()?.toDoubleOrNull()
|
|
|
|
|
- val warningAnnual = 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(";")
|
|
|
}
|
|
}
|
|
@@ -530,7 +338,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 data = if (clazz.simpleName == "PhoneUser") {
|
|
|
- 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) }
|
|
|
}
|
|
}
|
|
@@ -543,11 +351,14 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
val finalMap = finalizer.filterNot { fi ->
|
|
val finalMap = finalizer.filterNot { fi ->
|
|
|
listOf(
|
|
listOf(
|
|
|
"pbx.list",
|
|
"pbx.list",
|
|
|
|
|
+ "pbx__list",
|
|
|
"pbx_id",
|
|
"pbx_id",
|
|
|
"extension",
|
|
"extension",
|
|
|
"pin",
|
|
"pin",
|
|
|
"budget.maxCost",
|
|
"budget.maxCost",
|
|
|
|
|
+ "budget__maxCost",
|
|
|
"budget.warnCost",
|
|
"budget.warnCost",
|
|
|
|
|
+ "budget__warnCost",
|
|
|
"maxCost",
|
|
"maxCost",
|
|
|
"warnCost"
|
|
"warnCost"
|
|
|
).any { a -> a == fi.key }
|
|
).any { a -> a == fi.key }
|
|
@@ -558,7 +369,7 @@ class MigrationEntity(val passwordEncoder: PasswordEncoder, val queryNativeServi
|
|
|
}
|
|
}
|
|
|
}]"
|
|
}]"
|
|
|
if (phoneUserPbxIds.isEmpty()) {
|
|
if (phoneUserPbxIds.isEmpty()) {
|
|
|
- finalMap["expiredDate"] = LocalDate.now().atStartOfDay()
|
|
|
|
|
|
|
+ finalMap["expiredDate"] = finalMap["expiredDate"] ?: LocalDate.now().atStartOfDay()
|
|
|
}
|
|
}
|
|
|
queryNativeService.insertDataWithNativeQuery(clazz, finalMap)
|
|
queryNativeService.insertDataWithNativeQuery(clazz, finalMap)
|
|
|
} else {
|
|
} else {
|