Compute age from valid DOB in extraction
All checks were successful
build-and-deploy / build-deploy (push) Successful in 34s

This commit is contained in:
androidlover5842
2026-02-01 01:51:20 +05:30
parent 8e73217792
commit e68e7c685c

View File

@@ -11,6 +11,12 @@ import com.android.trisolarisserver.repo.PropertyRepo
import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import java.time.OffsetDateTime import java.time.OffsetDateTime
import java.time.LocalDate
import java.time.Period
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeFormatterBuilder
import java.time.format.ResolverStyle
import java.util.UUID import java.util.UUID
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@@ -268,6 +274,7 @@ class DocumentExtractionService(
normalizeIdNumber(results) normalizeIdNumber(results)
logIdNumber("after-normalize-id-digits", document.id, results) logIdNumber("after-normalize-id-digits", document.id, results)
normalizeAddress(results) normalizeAddress(results)
computeAgeIfDobPresent(results, propertyId)
applyBookingCityUpdates(document, results) applyBookingCityUpdates(document, results)
// Final Aadhaar checksum pass before doc type decision. // Final Aadhaar checksum pass before doc type decision.
markAadhaarIfValid(results) markAadhaarIfValid(results)
@@ -317,6 +324,18 @@ class DocumentExtractionService(
results[key] = normalized results[key] = normalized
} }
private fun computeAgeIfDobPresent(results: MutableMap<String, String>, propertyId: UUID) {
val dobRaw = cleanedValue(results[DocumentPrompts.DOB.first]) ?: return
val dob = parseDob(dobRaw) ?: return
val property = propertyRepo.findById(propertyId).orElse(null) ?: return
val zone = runCatching { ZoneId.of(property.timezone) }.getOrNull() ?: ZoneId.systemDefault()
val today = LocalDate.now(zone)
val years = Period.between(dob, today).years
if (years in 0..120) {
results["age"] = years.toString()
}
}
private fun markAadhaarIfValid(results: MutableMap<String, String>) { private fun markAadhaarIfValid(results: MutableMap<String, String>) {
val idKey = DocumentPrompts.ID_NUMBER.first val idKey = DocumentPrompts.ID_NUMBER.first
val digits = normalizeDigits(cleanedValue(results[idKey])) val digits = normalizeDigits(cleanedValue(results[idKey]))
@@ -696,6 +715,24 @@ private fun unorderedMatchCount(a: String, b: String): Int {
} }
return total return total
} }
private fun parseDob(value: String): LocalDate? {
val cleaned = value.trim().replace(Regex("\\s+"), "")
val formatters = listOf(
DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("dd/MM/uuuu").toFormatter(),
DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("dd-MM-uuuu").toFormatter(),
DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("uuuu-MM-dd").toFormatter(),
DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("uuuu/MM/dd").toFormatter()
).map { it.withResolverStyle(ResolverStyle.STRICT) }
for (formatter in formatters) {
try {
return LocalDate.parse(cleaned, formatter)
} catch (_: Exception) {
}
}
return null
}
private fun extractPinFromValue(value: String?): String? { private fun extractPinFromValue(value: String?): String? {
if (value.isNullOrBlank()) return null if (value.isNullOrBlank()) return null
val compact = value.replace(Regex("\\s+"), "") val compact = value.replace(Regex("\\s+"), "")