From da1ee5071231ab5db1d2bdbb0098fa5659d5b0c0 Mon Sep 17 00:00:00 2001 From: Eugene Zadyra Date: Tue, 11 Dec 2018 15:34:11 +0100 Subject: [PATCH] Ask user to update term if service is already booked --- .../com/lbs/server/conversation/Book.scala | 25 ++++++++++-- .../main/scala/com/lbs/server/lang/En.scala | 2 + .../main/scala/com/lbs/server/lang/Lang.scala | 2 + .../main/scala/com/lbs/server/lang/Ua.scala | 2 + .../com/lbs/server/service/ApiService.scala | 39 ++++++++++++------- .../server/service/MonitoringService.scala | 6 +-- 6 files changed, 54 insertions(+), 22 deletions(-) diff --git a/server/src/main/scala/com/lbs/server/conversation/Book.scala b/server/src/main/scala/com/lbs/server/conversation/Book.scala index a78c392..434e6f7 100644 --- a/server/src/main/scala/com/lbs/server/conversation/Book.scala +++ b/server/src/main/scala/com/lbs/server/conversation/Book.scala @@ -145,8 +145,10 @@ class Book(val userId: UserId, bot: Bot, apiService: ApiService, dataService: Da val response = apiService.temporaryReservation(userId.accountId, term.mapTo[TemporaryReservationRequest], term.mapTo[ValuationsRequest]) response match { case Left(ex) => - bot.sendMessage(userId.source, ex.getMessage) - end() + warn(s"Service [${bookingData.serviceId.name}] is already booked. Ask to update term", ex) + bot.sendMessage(userId.source, lang.visitAlreadyExists, + inlineKeyboard = createInlineKeyboard(Seq(Button(lang.yes, Tags.RebookYes), Button(lang.no, Tags.RebookNo)), columns = 1)) + goto(awaitRebookDecision) using bookingData.copy(term = Some(term)) case Right((temporaryReservation, valuations)) => bot.sendMessage(userId.source, lang.confirmAppointment(term, valuations), inlineKeyboard = createInlineKeyboard(Seq(Button(lang.cancel, Tags.Cancel), Button(lang.book, Tags.Book)))) @@ -168,6 +170,23 @@ class Book(val userId: UserId, bot: Bot, apiService: ApiService, dataService: Da goto(askMonitoringAutobookOption) } + private def awaitRebookDecision: Step = + monologue { + case Msg(CallbackCommand(Tags.RebookYes), bookingData: BookingData) => + apiService.updateReservedVisit(userId.accountId, bookingData.term.get) match { + case Right(success) => + debug(s"Successfully confirmed: $success") + bot.sendMessage(userId.source, lang.appointmentIsConfirmed) + case Left(ex) => + error("Error during reservation", ex) + bot.sendMessage(userId.source, ex.getMessage) + } + end() + case Msg(CallbackCommand(Tags.RebookNo), _) => + info("User doesn't want to change term") + end() + } + private def awaitReservation: Step = monologue { case Msg(CallbackCommand(Tags.Cancel), bookingData: BookingData) => @@ -207,7 +226,7 @@ class Book(val userId: UserId, bot: Bot, apiService: ApiService, dataService: Da } onReply { case Msg(CallbackCommand(BooleanString(autobook)), bookingData: BookingData) => val data = bookingData.copy(autobook = autobook) - if(autobook) goto(askMonitoringRebookOption) using data + if (autobook) goto(askMonitoringRebookOption) using data else goto(createMonitoring) using data } diff --git a/server/src/main/scala/com/lbs/server/lang/En.scala b/server/src/main/scala/com/lbs/server/lang/En.scala index cec8b61..5b5d663 100644 --- a/server/src/main/scala/com/lbs/server/lang/En.scala +++ b/server/src/main/scala/com/lbs/server/lang/En.scala @@ -97,6 +97,8 @@ object En extends Lang { override def rebookIfExists: String = " Do you want to update term if reservation already exists?" + override def visitAlreadyExists: String = " The same service is already booked. Do you want to update term?" + override def city: String = "city" override def clinic: String = "clinic" diff --git a/server/src/main/scala/com/lbs/server/lang/Lang.scala b/server/src/main/scala/com/lbs/server/lang/Lang.scala index 0ce376a..16dc85e 100644 --- a/server/src/main/scala/com/lbs/server/lang/Lang.scala +++ b/server/src/main/scala/com/lbs/server/lang/Lang.scala @@ -87,6 +87,8 @@ trait Lang { def rebookIfExists: String + def visitAlreadyExists: String + def city: String def clinic: String diff --git a/server/src/main/scala/com/lbs/server/lang/Ua.scala b/server/src/main/scala/com/lbs/server/lang/Ua.scala index 4f7307c..71b2dbd 100644 --- a/server/src/main/scala/com/lbs/server/lang/Ua.scala +++ b/server/src/main/scala/com/lbs/server/lang/Ua.scala @@ -97,6 +97,8 @@ object Ua extends Lang { override def rebookIfExists: String = " Чи хотіли би ви змінити термін в разі, якщо резервація вже існує?" + override def visitAlreadyExists: String = " Резервація для такого сервісу вже існує. Чі хотіли би ви змінити термін?" + override def city: String = "місто" override def clinic: String = "клініка" diff --git a/server/src/main/scala/com/lbs/server/service/ApiService.scala b/server/src/main/scala/com/lbs/server/service/ApiService.scala index 5a16fbc..df2d88c 100644 --- a/server/src/main/scala/com/lbs/server/service/ApiService.scala +++ b/server/src/main/scala/com/lbs/server/service/ApiService.scala @@ -138,20 +138,29 @@ class ApiService extends SessionSupport { LuxmedApi.changeTerm(session.accessToken, session.tokenType, reservationId, reservationRequest) } - def updateTerm(accountId: Long, reservationId: Long, term: AvailableVisitsTermPresentation): Either[Throwable, ChangeTermResponse] = { - val temporaryReservationRequest = term.mapTo[TemporaryReservationRequest] - val valuationsRequest = term.mapTo[ValuationsRequest] - val canTermBeChangedResponse = canTermBeChanged(accountId, reservationId) - if (canTermBeChangedResponse.exists(_.code == 204)) { - for { - okResponse <- temporaryReservationToChangeTerm(accountId, reservationId, temporaryReservationRequest, valuationsRequest) - (temporaryReservation, valuations) = okResponse - temporaryReservationId = temporaryReservation.id - visitTermVariant = valuations.visitTermVariants.head - reservationRequest = (temporaryReservationId, visitTermVariant, term).mapTo[ReservationRequest] - reservation <- changeTerm(accountId, reservationId, reservationRequest) - } yield reservation - } else Left(new RuntimeException(s"Term for reservation [$reservationId] can't be changed")) + def updateReservedVisit(accountId: Long, term: AvailableVisitsTermPresentation): Either[Throwable, ChangeTermResponse] = { + val reservedVisitEither = reservedVisits(accountId, toDate = ZonedDateTime.now().plusMonths(6)).map(_.find(_.service.id == term.serviceId)) + reservedVisitEither match { + case Right(Some(reservedVisit: ReservedVisit)) => + val reservationId = reservedVisit.reservationId + val temporaryReservationRequest = term.mapTo[TemporaryReservationRequest] + val valuationsRequest = term.mapTo[ValuationsRequest] + val canTermBeChangedResponse = canTermBeChanged(accountId, reservationId) + if (canTermBeChangedResponse.exists(_.code == 204)) { + for { + okResponse <- temporaryReservationToChangeTerm(accountId, reservationId, temporaryReservationRequest, valuationsRequest) + (temporaryReservation, valuations) = okResponse + temporaryReservationId = temporaryReservation.id + visitTermVariant = valuations.visitTermVariants.head + reservationRequest = (temporaryReservationId, visitTermVariant, term).mapTo[ReservationRequest] + reservation <- changeTerm(accountId, reservationId, reservationRequest) + } yield reservation + } else left(s"Term for reservation [$reservationId] can't be changed") + case Left(ex) => + Left(ex) + case _ => + left(s"Existing reservation for service [${term.serviceId}] not found. Nothing to update") + } } def visitsHistory(accountId: Long, fromDate: ZonedDateTime = ZonedDateTime.now().minusYears(1), @@ -175,4 +184,6 @@ class ApiService extends SessionSupport { LuxmedApi.login(username, textEncryptor.decrypt(password)) } + private def left(msg: String) = Left(new RuntimeException(msg)) + } diff --git a/server/src/main/scala/com/lbs/server/service/MonitoringService.scala b/server/src/main/scala/com/lbs/server/service/MonitoringService.scala index 814b2b4..893a294 100644 --- a/server/src/main/scala/com/lbs/server/service/MonitoringService.scala +++ b/server/src/main/scala/com/lbs/server/service/MonitoringService.scala @@ -149,11 +149,7 @@ class MonitoringService extends Logger { apiService.reserveVisit(monitoring.accountId, term).toTry.recoverWith { case _: ServiceIsAlreadyBookedException if monitoring.rebookIfExists => info(s"Service [${monitoring.serviceName}] is already booked. Trying to update term") - val reservation = apiService.reservedVisits(monitoring.accountId, toDate = ZonedDateTime.now().plusMonths(6)).map(_.head) - reservation.toTry.flatMap { r => - val reservationId = r.reservationId - apiService.updateTerm(monitoring.accountId, reservationId, term).toTry - } + apiService.updateReservedVisit(monitoring.accountId, term).toTry case ex => Failure(ex) }.toEither match { case Right(_) =>