Replace placeholder guest with existing phone guest
All checks were successful
build-and-deploy / build-deploy (push) Successful in 35s
All checks were successful
build-and-deploy / build-deploy (push) Successful in 35s
This commit is contained in:
@@ -8,6 +8,7 @@ import com.android.trisolarisserver.controller.dto.GuestVehicleRequest
|
||||
import com.android.trisolarisserver.models.booking.Guest
|
||||
import com.android.trisolarisserver.models.booking.GuestVehicle
|
||||
import com.android.trisolarisserver.db.repo.BookingRepo
|
||||
import com.android.trisolarisserver.db.repo.GuestDocumentRepo
|
||||
import com.android.trisolarisserver.db.repo.GuestRepo
|
||||
import com.android.trisolarisserver.db.repo.GuestRatingRepo
|
||||
import com.android.trisolarisserver.repo.AppUserRepo
|
||||
@@ -19,6 +20,7 @@ import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
import org.springframework.web.server.ResponseStatusException
|
||||
@@ -34,12 +36,14 @@ class Guests(
|
||||
private val bookingRepo: BookingRepo,
|
||||
private val guestVehicleRepo: GuestVehicleRepo,
|
||||
private val guestRatingRepo: GuestRatingRepo,
|
||||
private val guestDocumentRepo: GuestDocumentRepo,
|
||||
private val signatureStorage: GuestSignatureStorage,
|
||||
private val appUserRepo: AppUserRepo
|
||||
) {
|
||||
|
||||
@PostMapping
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@Transactional
|
||||
fun createGuest(
|
||||
@PathVariable propertyId: UUID,
|
||||
@AuthenticationPrincipal principal: MyPrincipal?,
|
||||
@@ -55,15 +59,26 @@ class Guests(
|
||||
if (booking.property.id != property.id) {
|
||||
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Booking not in property")
|
||||
}
|
||||
if (booking.primaryGuest != null) {
|
||||
throw ResponseStatusException(HttpStatus.CONFLICT, "Booking already linked to guest")
|
||||
val currentGuest = booking.primaryGuest
|
||||
if (currentGuest != null && phone == null) {
|
||||
if (!isPlaceholderGuest(currentGuest)) {
|
||||
throw ResponseStatusException(HttpStatus.CONFLICT, "Booking already linked to guest")
|
||||
}
|
||||
val updated = applyGuestDetails(currentGuest, request)
|
||||
booking.updatedAt = OffsetDateTime.now()
|
||||
bookingRepo.save(booking)
|
||||
return setOf(updated).toResponse(propertyId, guestVehicleRepo, guestRatingRepo).first()
|
||||
}
|
||||
if (phone != null) {
|
||||
val existing = guestRepo.findByPropertyIdAndPhoneE164(propertyId, phone)
|
||||
if (existing != null) {
|
||||
val previous = booking.primaryGuest
|
||||
booking.primaryGuest = existing
|
||||
booking.updatedAt = OffsetDateTime.now()
|
||||
bookingRepo.save(booking)
|
||||
if (previous != null && previous.id != existing.id && isPlaceholderGuest(previous) && isSafeToDelete(previous)) {
|
||||
guestRepo.delete(previous)
|
||||
}
|
||||
return setOf(existing).toResponse(propertyId, guestVehicleRepo, guestRatingRepo).first()
|
||||
}
|
||||
}
|
||||
@@ -196,6 +211,33 @@ class Guests(
|
||||
.body(resource)
|
||||
}
|
||||
|
||||
private fun applyGuestDetails(guest: Guest, request: GuestCreateRequest): Guest {
|
||||
val name = request.name?.trim()?.ifBlank { null }
|
||||
val nationality = request.nationality?.trim()?.ifBlank { null }
|
||||
val address = request.addressText?.trim()?.ifBlank { null }
|
||||
if (name != null) guest.name = name
|
||||
if (nationality != null) guest.nationality = nationality
|
||||
if (address != null) guest.addressText = address
|
||||
guest.updatedAt = OffsetDateTime.now()
|
||||
return guestRepo.save(guest)
|
||||
}
|
||||
|
||||
private fun isPlaceholderGuest(guest: Guest): Boolean {
|
||||
return guest.phoneE164.isNullOrBlank() &&
|
||||
guest.name.isNullOrBlank() &&
|
||||
guest.nationality.isNullOrBlank() &&
|
||||
guest.addressText.isNullOrBlank() &&
|
||||
guest.signaturePath.isNullOrBlank()
|
||||
}
|
||||
|
||||
private fun isSafeToDelete(guest: Guest): Boolean {
|
||||
val id = guest.id ?: return false
|
||||
if (bookingRepo.countByPrimaryGuestId(id) > 0) return false
|
||||
if (guestVehicleRepo.existsByGuestId(id)) return false
|
||||
if (guestDocumentRepo.existsByGuestId(id)) return false
|
||||
if (guestRatingRepo.existsByGuestId(id)) return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private fun Set<Guest>.toResponse(
|
||||
|
||||
@@ -7,4 +7,5 @@ import java.util.UUID
|
||||
interface BookingRepo : JpaRepository<Booking, UUID> {
|
||||
fun findByPropertyIdAndSourceBookingId(propertyId: UUID, sourceBookingId: String): Booking?
|
||||
fun existsByPropertyIdAndSourceBookingId(propertyId: UUID, sourceBookingId: String): Boolean
|
||||
fun countByPrimaryGuestId(guestId: UUID): Long
|
||||
}
|
||||
|
||||
@@ -7,4 +7,5 @@ import java.util.UUID
|
||||
interface GuestDocumentRepo : JpaRepository<GuestDocument, UUID> {
|
||||
fun findByPropertyIdAndGuestIdOrderByUploadedAtDesc(propertyId: UUID, guestId: UUID): List<GuestDocument>
|
||||
fun findByIdAndPropertyIdAndGuestId(id: UUID, propertyId: UUID, guestId: UUID): GuestDocument?
|
||||
fun existsByGuestId(guestId: UUID): Boolean
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.UUID
|
||||
interface GuestRatingRepo : JpaRepository<GuestRating, UUID> {
|
||||
fun findByGuestIdOrderByCreatedAtDesc(guestId: UUID): List<GuestRating>
|
||||
fun existsByGuestIdAndBookingId(guestId: UUID, bookingId: UUID): Boolean
|
||||
fun existsByGuestId(guestId: UUID): Boolean
|
||||
|
||||
@Query(
|
||||
"""
|
||||
|
||||
@@ -8,4 +8,5 @@ interface GuestVehicleRepo : JpaRepository<GuestVehicle, UUID> {
|
||||
fun findByPropertyIdAndVehicleNumberIgnoreCase(propertyId: UUID, vehicleNumber: String): GuestVehicle?
|
||||
fun findByGuestIdIn(guestIds: List<UUID>): List<GuestVehicle>
|
||||
fun existsByPropertyIdAndVehicleNumberIgnoreCase(propertyId: UUID, vehicleNumber: String): Boolean
|
||||
fun existsByGuestId(guestId: UUID): Boolean
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user