From 3546b2de62b9467a04b35759338b643bbecc5374 Mon Sep 17 00:00:00 2001 From: androidlover5842 Date: Thu, 29 Jan 2026 05:35:19 +0530 Subject: [PATCH] Allow rate plan code per room type --- .../config/RatePlanSchemaFix.kt | 42 +++++++++++++++++++ .../trisolarisserver/controller/RatePlans.kt | 6 +-- .../trisolarisserver/models/room/RatePlan.kt | 2 +- .../trisolarisserver/repo/RatePlanRepo.kt | 1 + 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 src/main/kotlin/com/android/trisolarisserver/config/RatePlanSchemaFix.kt diff --git a/src/main/kotlin/com/android/trisolarisserver/config/RatePlanSchemaFix.kt b/src/main/kotlin/com/android/trisolarisserver/config/RatePlanSchemaFix.kt new file mode 100644 index 0000000..6ad278a --- /dev/null +++ b/src/main/kotlin/com/android/trisolarisserver/config/RatePlanSchemaFix.kt @@ -0,0 +1,42 @@ +package com.android.trisolarisserver.config + +import org.springframework.jdbc.core.JdbcTemplate +import org.springframework.stereotype.Component + +@Component +class RatePlanSchemaFix( + private val jdbcTemplate: JdbcTemplate +) : PostgresSchemaFix(jdbcTemplate) { + + override fun runPostgres(jdbcTemplate: JdbcTemplate) { + val constraints = jdbcTemplate.query( + """ + select tc.constraint_name, + array_agg(kcu.column_name order by kcu.ordinal_position) as cols + from information_schema.table_constraints tc + join information_schema.key_column_usage kcu + on tc.constraint_name = kcu.constraint_name + and tc.table_schema = kcu.table_schema + where tc.table_name = 'rate_plan' + and tc.constraint_type = 'UNIQUE' + group by tc.constraint_name + """.trimIndent() + ) { rs, _ -> + rs.getString("constraint_name") to (rs.getArray("cols").array as Array<*>).map { it.toString() } + } + + val oldConstraint = constraints.firstOrNull { it.second == listOf("property_id", "code") } + if (oldConstraint != null) { + logger.info("Dropping old unique constraint on rate_plan(property_id, code)") + jdbcTemplate.execute("alter table rate_plan drop constraint if exists ${oldConstraint.first}") + } + + val hasNew = constraints.any { it.second == listOf("property_id", "room_type_id", "code") } + if (!hasNew) { + logger.info("Adding unique constraint on rate_plan(property_id, room_type_id, code)") + jdbcTemplate.execute( + "alter table rate_plan add constraint rate_plan_property_roomtype_code_key unique (property_id, room_type_id, code)" + ) + } + } +} diff --git a/src/main/kotlin/com/android/trisolarisserver/controller/RatePlans.kt b/src/main/kotlin/com/android/trisolarisserver/controller/RatePlans.kt index 0961a2c..b73e460 100644 --- a/src/main/kotlin/com/android/trisolarisserver/controller/RatePlans.kt +++ b/src/main/kotlin/com/android/trisolarisserver/controller/RatePlans.kt @@ -50,14 +50,14 @@ class RatePlans( @RequestBody request: RatePlanCreateRequest ): RatePlanResponse { requireRole(propertyAccess, propertyId, principal, Role.ADMIN, Role.MANAGER) - if (ratePlanRepo.existsByPropertyIdAndCode(propertyId, request.code.trim())) { - throw ResponseStatusException(HttpStatus.CONFLICT, "Rate plan code already exists") - } val property = propertyRepo.findById(propertyId).orElseThrow { ResponseStatusException(HttpStatus.NOT_FOUND, "Property not found") } val roomType = roomTypeRepo.findByPropertyIdAndCodeIgnoreCase(propertyId, request.roomTypeCode) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Room type not found") + if (ratePlanRepo.existsByPropertyIdAndRoomTypeIdAndCode(propertyId, roomType.id!!, request.code.trim())) { + throw ResponseStatusException(HttpStatus.CONFLICT, "Rate plan code already exists for room type") + } val plan = RatePlan( property = property, diff --git a/src/main/kotlin/com/android/trisolarisserver/models/room/RatePlan.kt b/src/main/kotlin/com/android/trisolarisserver/models/room/RatePlan.kt index bf0df6e..2ce9f45 100644 --- a/src/main/kotlin/com/android/trisolarisserver/models/room/RatePlan.kt +++ b/src/main/kotlin/com/android/trisolarisserver/models/room/RatePlan.kt @@ -9,7 +9,7 @@ import java.util.UUID @Table( name = "rate_plan", uniqueConstraints = [ - UniqueConstraint(columnNames = ["property_id", "code"]) + UniqueConstraint(columnNames = ["property_id", "room_type_id", "code"]) ] ) class RatePlan( diff --git a/src/main/kotlin/com/android/trisolarisserver/repo/RatePlanRepo.kt b/src/main/kotlin/com/android/trisolarisserver/repo/RatePlanRepo.kt index f2ca323..c1a8e84 100644 --- a/src/main/kotlin/com/android/trisolarisserver/repo/RatePlanRepo.kt +++ b/src/main/kotlin/com/android/trisolarisserver/repo/RatePlanRepo.kt @@ -10,4 +10,5 @@ interface RatePlanRepo : JpaRepository { fun findByPropertyIdOrderByCode(propertyId: UUID): List fun findByIdAndPropertyId(id: UUID, propertyId: UUID): RatePlan? fun existsByPropertyIdAndCode(propertyId: UUID, code: String): Boolean + fun existsByPropertyIdAndRoomTypeIdAndCode(propertyId: UUID, roomTypeId: UUID, code: String): Boolean }