Remove room-stay change-rate endpoint
All checks were successful
build-and-deploy / build-deploy (push) Successful in 34s
All checks were successful
build-and-deploy / build-deploy (push) Successful in 34s
This commit is contained in:
@@ -6,10 +6,7 @@ import com.android.trisolarisserver.controller.common.requireRoomStayForProperty
|
|||||||
import com.android.trisolarisserver.component.auth.PropertyAccess
|
import com.android.trisolarisserver.component.auth.PropertyAccess
|
||||||
import com.android.trisolarisserver.controller.dto.booking.RoomStayVoidRequest
|
import com.android.trisolarisserver.controller.dto.booking.RoomStayVoidRequest
|
||||||
import com.android.trisolarisserver.controller.dto.room.ActiveRoomStayResponse
|
import com.android.trisolarisserver.controller.dto.room.ActiveRoomStayResponse
|
||||||
import com.android.trisolarisserver.controller.dto.rate.RoomStayRateChangeRequest
|
|
||||||
import com.android.trisolarisserver.controller.dto.rate.RoomStayRateChangeResponse
|
|
||||||
import com.android.trisolarisserver.models.property.Role
|
import com.android.trisolarisserver.models.property.Role
|
||||||
import com.android.trisolarisserver.models.room.RateSource
|
|
||||||
import com.android.trisolarisserver.models.room.RoomStayAuditLog
|
import com.android.trisolarisserver.models.room.RoomStayAuditLog
|
||||||
import com.android.trisolarisserver.models.room.RoomStay
|
import com.android.trisolarisserver.models.room.RoomStay
|
||||||
import com.android.trisolarisserver.repo.booking.BookingRepo
|
import com.android.trisolarisserver.repo.booking.BookingRepo
|
||||||
@@ -77,47 +74,6 @@ class RoomStays(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/properties/{propertyId}/room-stays/{roomStayId}/change-rate")
|
|
||||||
fun changeRate(
|
|
||||||
@PathVariable propertyId: UUID,
|
|
||||||
@PathVariable roomStayId: UUID,
|
|
||||||
@AuthenticationPrincipal principal: MyPrincipal?,
|
|
||||||
@RequestBody request: RoomStayRateChangeRequest
|
|
||||||
): RoomStayRateChangeResponse {
|
|
||||||
val actor = requireMember(propertyAccess, propertyId, principal)
|
|
||||||
val stay = requireRoomStayForProperty(roomStayRepo, propertyId, roomStayId)
|
|
||||||
val roles = propertyUserRepo.findRolesByPropertyAndUser(propertyId, actor.userId)
|
|
||||||
val hasPrivilegedRole = roles.contains(Role.ADMIN) || roles.contains(Role.MANAGER)
|
|
||||||
val hasStaffRole = roles.contains(Role.STAFF)
|
|
||||||
if (!hasPrivilegedRole && !hasStaffRole) {
|
|
||||||
throw ResponseStatusException(HttpStatus.FORBIDDEN, "Missing role")
|
|
||||||
}
|
|
||||||
if (!hasPrivilegedRole && paymentRepo.existsByBookingId(stay.booking.id!!)) {
|
|
||||||
throw ResponseStatusException(
|
|
||||||
HttpStatus.FORBIDDEN,
|
|
||||||
"Rate changes are locked after first payment"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val effectiveAt = parseOffset(request.effectiveAt)
|
|
||||||
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "effectiveAt required")
|
|
||||||
if (!effectiveAt.isAfter(stay.fromAt)) {
|
|
||||||
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "effectiveAt must be after fromAt")
|
|
||||||
}
|
|
||||||
if (stay.toAt != null && !effectiveAt.isBefore(stay.toAt)) {
|
|
||||||
throw ResponseStatusException(HttpStatus.CONFLICT, "effectiveAt outside stay range")
|
|
||||||
}
|
|
||||||
|
|
||||||
val newStay = splitStay(stay, effectiveAt, request)
|
|
||||||
roomStayRepo.save(stay)
|
|
||||||
roomStayRepo.save(newStay)
|
|
||||||
return RoomStayRateChangeResponse(
|
|
||||||
oldRoomStayId = stay.id!!,
|
|
||||||
newRoomStayId = newStay.id!!,
|
|
||||||
effectiveAt = effectiveAt.toString()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/properties/{propertyId}/room-stays/{roomStayId}/void")
|
@PostMapping("/properties/{propertyId}/room-stays/{roomStayId}/void")
|
||||||
fun voidRoomStay(
|
fun voidRoomStay(
|
||||||
@PathVariable propertyId: UUID,
|
@PathVariable propertyId: UUID,
|
||||||
@@ -173,31 +129,6 @@ class RoomStays(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun splitStay(stay: RoomStay, effectiveAt: OffsetDateTime, request: RoomStayRateChangeRequest): RoomStay {
|
|
||||||
val oldToAt = stay.toAt
|
|
||||||
stay.toAt = effectiveAt
|
|
||||||
return RoomStay(
|
|
||||||
property = stay.property,
|
|
||||||
booking = stay.booking,
|
|
||||||
room = stay.room,
|
|
||||||
fromAt = effectiveAt,
|
|
||||||
toAt = oldToAt,
|
|
||||||
rateSource = parseRateSource(request.rateSource),
|
|
||||||
nightlyRate = request.nightlyRate,
|
|
||||||
ratePlanCode = request.ratePlanCode,
|
|
||||||
currency = request.currency ?: stay.property.currency,
|
|
||||||
createdBy = stay.createdBy
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseRateSource(value: String): RateSource {
|
|
||||||
return try {
|
|
||||||
RateSource.valueOf(value.trim().uppercase())
|
|
||||||
} catch (_: IllegalArgumentException) {
|
|
||||||
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Unknown rate source")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isAgentOnly(roles: Set<Role>): Boolean {
|
private fun isAgentOnly(roles: Set<Role>): Boolean {
|
||||||
if (!roles.contains(Role.AGENT)) return false
|
if (!roles.contains(Role.AGENT)) return false
|
||||||
val privileged = setOf(
|
val privileged = setOf(
|
||||||
|
|||||||
Reference in New Issue
Block a user