From cac3f272a2f1373d6f411924ff0060e34f672b80 Mon Sep 17 00:00:00 2001 From: androidlover5842 Date: Sat, 7 Feb 2026 22:30:54 +0530 Subject: [PATCH] Fix booking profile request parsing without JsonNode --- .../controller/booking/BookingFlow.kt | 87 ++++++++++--------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt b/src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt index c9e61d2..a468de8 100644 --- a/src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt +++ b/src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt @@ -53,7 +53,6 @@ import com.android.trisolarisserver.repo.room.RoomRepo import com.android.trisolarisserver.repo.room.RoomStayAuditLogRepo import com.android.trisolarisserver.repo.room.RoomStayRepo import com.android.trisolarisserver.security.MyPrincipal -import com.fasterxml.jackson.databind.JsonNode import jakarta.servlet.http.HttpServletResponse import org.springframework.http.HttpStatus import org.springframework.security.core.annotation.AuthenticationPrincipal @@ -643,12 +642,9 @@ class BookingFlow( @PathVariable propertyId: UUID, @PathVariable bookingId: UUID, @AuthenticationPrincipal principal: MyPrincipal?, - @RequestBody request: JsonNode + @RequestBody request: Map ) { requireRole(propertyAccess, propertyId, principal, Role.ADMIN, Role.MANAGER) - if (!request.isObject) { - throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid request body") - } val allowedFields = setOf( "transportMode", @@ -659,7 +655,7 @@ class BookingFlow( "toCity", "memberRelation" ) - val fieldNames = request.fieldNames().asSequence().toList() + val fieldNames = request.keys.toList() val unknownFields = fieldNames.filter { it !in allowedFields } if (unknownFields.isNotEmpty()) { throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Unknown fields: ${unknownFields.joinToString(",")}") @@ -670,34 +666,34 @@ class BookingFlow( val booking = requireBooking(propertyId, bookingId) - if (request.has("transportMode")) { - val transportNode = request.get("transportMode") - booking.transportMode = parseNullableTransportMode(booking, transportNode) + if (request.containsKey("transportMode")) { + booking.transportMode = parseNullableTransportMode(booking, request["transportMode"]) } - if (request.has("fromCity")) { - booking.fromCity = parseNullableText(request.get("fromCity"), "fromCity") + if (request.containsKey("fromCity")) { + booking.fromCity = parseNullableText(request["fromCity"], "fromCity") } - if (request.has("toCity")) { - booking.toCity = parseNullableText(request.get("toCity"), "toCity") + if (request.containsKey("toCity")) { + booking.toCity = parseNullableText(request["toCity"], "toCity") } - if (request.has("memberRelation")) { - booking.memberRelation = parseNullableMemberRelation(request.get("memberRelation")) + if (request.containsKey("memberRelation")) { + booking.memberRelation = parseNullableMemberRelation(request["memberRelation"]) } - val hasGuestCountPatch = request.has("maleCount") || request.has("femaleCount") || request.has("childCount") + val hasGuestCountPatch = + request.containsKey("maleCount") || request.containsKey("femaleCount") || request.containsKey("childCount") if (hasGuestCountPatch) { - val maleCount = if (request.has("maleCount")) { - parseNullableNonNegativeInt(request.get("maleCount"), "maleCount") + val maleCount = if (request.containsKey("maleCount")) { + parseNullableNonNegativeInt(request["maleCount"], "maleCount") } else { booking.maleCount } - val femaleCount = if (request.has("femaleCount")) { - parseNullableNonNegativeInt(request.get("femaleCount"), "femaleCount") + val femaleCount = if (request.containsKey("femaleCount")) { + parseNullableNonNegativeInt(request["femaleCount"], "femaleCount") } else { booking.femaleCount } - val childCount = if (request.has("childCount")) { - parseNullableNonNegativeInt(request.get("childCount"), "childCount") + val childCount = if (request.containsKey("childCount")) { + parseNullableNonNegativeInt(request["childCount"], "childCount") } else { booking.childCount } @@ -1036,13 +1032,13 @@ class BookingFlow( private fun parseNullableTransportMode( booking: com.android.trisolarisserver.models.booking.Booking, - node: JsonNode? + value: Any? ): TransportMode? { - if (node == null || node.isNull) return null - if (!node.isTextual) { + if (value == null) return null + if (value !is String) { throw ResponseStatusException(HttpStatus.BAD_REQUEST, "transportMode must be string or null") } - val raw = node.asText().trim() + val raw = value.trim() if (raw.isBlank()) return null val mode = parseTransportMode(raw.uppercase()) if (!isTransportModeAllowed(booking.property, mode)) { @@ -1060,34 +1056,41 @@ class BookingFlow( } } - private fun parseNullableMemberRelation(node: JsonNode?): MemberRelation? { - if (node == null || node.isNull) return null - if (!node.isTextual) { + private fun parseNullableMemberRelation(value: Any?): MemberRelation? { + if (value == null) return null + if (value !is String) { throw ResponseStatusException(HttpStatus.BAD_REQUEST, "memberRelation must be string or null") } - return parseMemberRelation(node.asText()) + return parseMemberRelation(value) } - private fun parseNullableText(node: JsonNode?, fieldName: String): String? { - if (node == null || node.isNull) return null - if (!node.isTextual) { + private fun parseNullableText(value: Any?, fieldName: String): String? { + if (value == null) return null + if (value !is String) { throw ResponseStatusException(HttpStatus.BAD_REQUEST, "$fieldName must be string or null") } - return node.asText().trim().ifBlank { null } + return value.trim().ifBlank { null } } - private fun parseNullableNonNegativeInt(node: JsonNode?, fieldName: String): Int? { - if (node == null || node.isNull) return null - if (!node.isIntegralNumber) { - throw ResponseStatusException(HttpStatus.BAD_REQUEST, "$fieldName must be integer or null") + private fun parseNullableNonNegativeInt(value: Any?, fieldName: String): Int? { + if (value == null) return null + val intValue = when (value) { + is Int -> value + is Long -> value.toInt() + is Number -> { + val asDouble = value.toDouble() + if (asDouble % 1.0 != 0.0) { + throw ResponseStatusException(HttpStatus.BAD_REQUEST, "$fieldName must be integer or null") + } + asDouble.toInt() + } + else -> throw ResponseStatusException(HttpStatus.BAD_REQUEST, "$fieldName must be integer or null") } - val value = node.asInt() - if (value < 0) { + if (intValue < 0) { throw ResponseStatusException(HttpStatus.BAD_REQUEST, "$fieldName must be >= 0") } - return value + return intValue } - private fun parseRateSource(value: String?): RateSource? { if (value.isNullOrBlank()) return null return try {