mirror of
https://github.com/dyrkin/luxmed-bot.git
synced 2025-12-21 13:23:05 +01:00
Fixed date time selection. Time matters from now
This commit is contained in:
@@ -74,7 +74,7 @@ class BootConfig {
|
||||
|
||||
@Bean
|
||||
def bookingActorFactory: ByUserIdActorFactory = userId => actorSystem.actorOf(Book.props(userId, bot, apiService, dataService,
|
||||
monitoringService, localization, datePickerFactory, staticDataActorFactory, termsPagerActorFactory))
|
||||
monitoringService, localization, datePickerFactory, timePickerFactory, staticDataActorFactory, termsPagerActorFactory))
|
||||
|
||||
@Bean
|
||||
def unauthorizedHelpActorFactory: ByMessageSourceActorFactory = source => actorSystem.actorOf(UnauthorizedHelp.props(source, bot))
|
||||
@@ -115,6 +115,10 @@ class BootConfig {
|
||||
def datePickerFactory: ByUserIdWithOriginatorActorFactory = (userId, originator) =>
|
||||
actorSystem.actorOf(DatePicker.props(userId, bot, localization, originator))
|
||||
|
||||
@Bean
|
||||
def timePickerFactory: ByUserIdWithOriginatorActorFactory = (userId, originator) =>
|
||||
actorSystem.actorOf(TimePicker.props(userId, bot, localization, originator))
|
||||
|
||||
@Bean
|
||||
def staticDataActorFactory: ByUserIdWithOriginatorActorFactory = (userId, originator) =>
|
||||
actorSystem.actorOf(StaticData.props(userId, bot, localization, originator))
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
package com.lbs.server.actor
|
||||
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.{LocalTime, ZonedDateTime}
|
||||
|
||||
import akka.actor.{PoisonPill, Props}
|
||||
import com.lbs.api.json.model._
|
||||
@@ -33,6 +33,7 @@ import com.lbs.server.actor.Book._
|
||||
import com.lbs.server.actor.DatePicker.{DateFromMode, DateToMode}
|
||||
import com.lbs.server.actor.Login.UserId
|
||||
import com.lbs.server.actor.StaticData.StaticDataConfig
|
||||
import com.lbs.server.actor.TimePicker.{TimeFromMode, TimeToMode}
|
||||
import com.lbs.server.actor.conversation.Conversation
|
||||
import com.lbs.server.actor.conversation.Conversation.{InitConversation, StartConversation}
|
||||
import com.lbs.server.lang.{Localizable, Localization}
|
||||
@@ -42,10 +43,11 @@ import com.lbs.server.util.MessageExtractors.CallbackCommand
|
||||
import com.lbs.server.util.ServerModelConverters._
|
||||
|
||||
class Book(val userId: UserId, bot: Bot, apiService: ApiService, dataService: DataService, monitoringService: MonitoringService,
|
||||
val localization: Localization, datePickerActorFactory: ByUserIdWithOriginatorActorFactory, staticDataActorFactory: ByUserIdWithOriginatorActorFactory,
|
||||
termsPagerActorFactory: ByUserIdWithOriginatorActorFactory) extends Conversation[BookingData] with StaticDataForBooking with Localizable {
|
||||
val localization: Localization, datePickerActorFactory: ByUserIdWithOriginatorActorFactory, timePickerActorFactory: ByUserIdWithOriginatorActorFactory,
|
||||
staticDataActorFactory: ByUserIdWithOriginatorActorFactory, termsPagerActorFactory: ByUserIdWithOriginatorActorFactory) extends Conversation[BookingData] with StaticDataForBooking with Localizable {
|
||||
|
||||
private val datePicker = datePickerActorFactory(userId, self)
|
||||
private val timePicker = timePickerActorFactory(userId, self)
|
||||
private[actor] val staticData = staticDataActorFactory(userId, self)
|
||||
private val termsPager = termsPagerActorFactory(userId, self)
|
||||
|
||||
@@ -108,7 +110,35 @@ class Book(val userId: UserId, bot: Bot, apiService: ApiService, dataService: Da
|
||||
datePicker ! cmd
|
||||
stay()
|
||||
case Msg(date: ZonedDateTime, bookingData: BookingData) =>
|
||||
goto(requestAction) using bookingData.copy(dateTo = date)
|
||||
goto(requestTimeFrom) using bookingData.copy(dateTo = date)
|
||||
}
|
||||
|
||||
private def requestTimeFrom: Step =
|
||||
ask { bookingData =>
|
||||
timePicker ! InitConversation
|
||||
timePicker ! StartConversation
|
||||
timePicker ! TimeFromMode
|
||||
timePicker ! bookingData.timeFrom
|
||||
} onReply {
|
||||
case Msg(cmd: Command, _) =>
|
||||
timePicker ! cmd
|
||||
stay()
|
||||
case Msg(time: LocalTime, bookingData: BookingData) =>
|
||||
goto(requestTimeTo) using bookingData.copy(timeFrom = time)
|
||||
}
|
||||
|
||||
private def requestTimeTo: Step =
|
||||
ask { bookingData =>
|
||||
timePicker ! InitConversation
|
||||
timePicker ! StartConversation
|
||||
timePicker ! TimeToMode
|
||||
timePicker ! bookingData.timeTo
|
||||
} onReply {
|
||||
case Msg(cmd: Command, _) =>
|
||||
timePicker ! cmd
|
||||
stay()
|
||||
case Msg(time: LocalTime, bookingData: BookingData) =>
|
||||
goto(requestAction) using bookingData.copy(timeTo = time)
|
||||
}
|
||||
|
||||
private def requestAction: Step =
|
||||
@@ -130,7 +160,7 @@ class Book(val userId: UserId, bot: Bot, apiService: ApiService, dataService: Da
|
||||
ask { bookingData =>
|
||||
val availableTerms = apiService.getAvailableTerms(userId.accountId, bookingData.cityId.id,
|
||||
bookingData.clinicId.optionalId, bookingData.serviceId.id, bookingData.doctorId.optionalId,
|
||||
bookingData.dateFrom, Some(bookingData.dateTo), timeOfDay = bookingData.timeOfDay)
|
||||
bookingData.dateFrom, Some(bookingData.dateTo), timeFrom = bookingData.timeFrom, timeTo = bookingData.timeTo)
|
||||
termsPager ! InitConversation
|
||||
termsPager ! StartConversation
|
||||
termsPager ! availableTerms
|
||||
@@ -229,6 +259,7 @@ class Book(val userId: UserId, bot: Bot, apiService: ApiService, dataService: Da
|
||||
datePicker ! PoisonPill
|
||||
staticData ! PoisonPill
|
||||
termsPager ! PoisonPill
|
||||
timePicker ! PoisonPill
|
||||
super.postStop()
|
||||
}
|
||||
}
|
||||
@@ -237,13 +268,14 @@ object Book {
|
||||
|
||||
def props(userId: UserId, bot: Bot, apiService: ApiService, dataService: DataService, monitoringService: MonitoringService,
|
||||
localization: Localization, datePickerActorFactory: ByUserIdWithOriginatorActorFactory,
|
||||
timePickerFactory: ByUserIdWithOriginatorActorFactory,
|
||||
staticDataActorFactory: ByUserIdWithOriginatorActorFactory, termsPagerActorFactory: ByUserIdWithOriginatorActorFactory): Props =
|
||||
Props(new Book(userId, bot, apiService, dataService, monitoringService, localization, datePickerActorFactory,
|
||||
staticDataActorFactory, termsPagerActorFactory))
|
||||
timePickerFactory, staticDataActorFactory, termsPagerActorFactory))
|
||||
|
||||
case class BookingData(cityId: IdName = null, clinicId: IdName = null,
|
||||
serviceId: IdName = null, doctorId: IdName = null, dateFrom: ZonedDateTime = ZonedDateTime.now(),
|
||||
dateTo: ZonedDateTime = ZonedDateTime.now().plusDays(1L), timeOfDay: Int = 0, autobook: Boolean = false, term: Option[AvailableVisitsTermPresentation] = None,
|
||||
dateTo: ZonedDateTime = ZonedDateTime.now().plusDays(1L), timeFrom: LocalTime = LocalTime.of(7, 0), timeTo: LocalTime = LocalTime.of(21, 0), autobook: Boolean = false, term: Option[AvailableVisitsTermPresentation] = None,
|
||||
temporaryReservationId: Option[Long] = None, valuations: Option[ValuationsResponse] = None)
|
||||
|
||||
object Tags {
|
||||
|
||||
128
server/src/main/scala/com/lbs/server/actor/TimePicker.scala
Normal file
128
server/src/main/scala/com/lbs/server/actor/TimePicker.scala
Normal file
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018 Yevhen Zadyra
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.lbs.server.actor
|
||||
|
||||
import java.time.LocalTime
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import com.lbs.bot.model.{Button, Command}
|
||||
import com.lbs.bot.{Bot, _}
|
||||
import com.lbs.server.actor.Login.UserId
|
||||
import com.lbs.server.actor.TimePicker.{Mode, Tags, TimeFromMode, TimeToMode}
|
||||
import com.lbs.server.actor.conversation.Conversation
|
||||
import com.lbs.server.lang.{Localizable, Localization}
|
||||
|
||||
/**
|
||||
* Time picker Inline Keyboard
|
||||
*
|
||||
* ⬆ ⬆
|
||||
* HH mm
|
||||
* ⬇ ⬇
|
||||
*
|
||||
*/
|
||||
class TimePicker(val userId: UserId, val bot: Bot, val localization: Localization, originator: ActorRef) extends Conversation[LocalTime] with Localizable {
|
||||
|
||||
private var mode: Mode = TimeFromMode
|
||||
|
||||
entryPoint(configure)
|
||||
|
||||
def configure: Step =
|
||||
monologue {
|
||||
case Msg(newMode: Mode, _) =>
|
||||
mode = newMode
|
||||
stay()
|
||||
case Msg(initialTime: LocalTime, _) =>
|
||||
goto(requestTime) using initialTime
|
||||
}
|
||||
|
||||
def requestTime: Step =
|
||||
ask { initialDate =>
|
||||
val message = mode match {
|
||||
case TimeFromMode => lang.chooseTimeFrom
|
||||
case TimeToMode => lang.chooseTimeTo
|
||||
}
|
||||
bot.sendMessage(userId.source, message, inlineKeyboard = timeButtons(initialDate))
|
||||
} onReply {
|
||||
case Msg(Command(_, msg, Some(Tags.Done)), finalTime) =>
|
||||
val (message, updateTime) = mode match {
|
||||
case TimeFromMode =>
|
||||
val startOfTheWorkingDay = LocalTime.of(7, 0)
|
||||
val timeFrom = if (startOfTheWorkingDay.isBefore(LocalTime.now())) finalTime else startOfTheWorkingDay
|
||||
lang.timeFromIs(timeFrom) -> timeFrom
|
||||
case TimeToMode =>
|
||||
val timeTo = finalTime
|
||||
lang.timeToIs(timeTo) -> timeTo
|
||||
}
|
||||
bot.sendEditMessage(userId.source, msg.messageId, message)
|
||||
originator ! updateTime
|
||||
goto(configure) using null
|
||||
|
||||
case Msg(Command(_, msg, Some(tag)), time) =>
|
||||
val modifiedTime = modifyTime(time, tag)
|
||||
bot.sendEditMessage(userId.source, msg.messageId, inlineKeyboard = timeButtons(modifiedTime))
|
||||
stay() using modifiedTime
|
||||
}
|
||||
|
||||
private def modifyTime(time: LocalTime, tag: String) = {
|
||||
tag match {
|
||||
case Tags.HourInc => time.plusHours(1)
|
||||
case Tags.MinuteInc => time.plusMinutes(30)
|
||||
case Tags.HourDec => time.minusHours(1)
|
||||
case Tags.MinuteDec => time.minusMinutes(30)
|
||||
}
|
||||
}
|
||||
|
||||
private def timeButtons(time: LocalTime) = {
|
||||
val hour = f"${time.getHour}%02d"
|
||||
val minute = f"${time.getMinute}%02d"
|
||||
|
||||
createInlineKeyboard(Seq(
|
||||
Seq(Button("⬆", Tags.HourInc), Button("⬆", Tags.MinuteInc)),
|
||||
Seq(Button(hour), Button(minute)),
|
||||
Seq(Button("⬇", Tags.HourDec), Button("⬇", Tags.MinuteDec)),
|
||||
Seq(Button("Done", Tags.Done))
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
object TimePicker {
|
||||
def props(userId: UserId, bot: Bot, localization: Localization, originator: ActorRef): Props =
|
||||
Props(new TimePicker(userId, bot, localization, originator))
|
||||
|
||||
trait Mode
|
||||
|
||||
object TimeFromMode extends Mode
|
||||
|
||||
object TimeToMode extends Mode
|
||||
|
||||
object Tags {
|
||||
val HourInc = "hour_inc"
|
||||
val MinuteInc = "minute_inc"
|
||||
val HourDec = "hour_dec"
|
||||
val MinuteDec = "minute_dec"
|
||||
val Done = "done"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
*/
|
||||
package com.lbs.server.lang
|
||||
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.{LocalTime, ZonedDateTime}
|
||||
import java.util.Locale
|
||||
|
||||
import com.lbs.api.json.model.{AvailableVisitsTermPresentation, HistoricVisit, ReservedVisit, ValuationsResponse}
|
||||
import com.lbs.server.actor.Book
|
||||
import com.lbs.server.actor.StaticData.StaticDataConfig
|
||||
import com.lbs.server.repository.model.{Bug, Monitoring}
|
||||
import com.lbs.server.util.DateTimeUtil.{formatDate, formatDateTime, minutesSinceBeginOf2018}
|
||||
import com.lbs.server.util.DateTimeUtil.{formatDate, formatDateTime, formatTime, minutesSinceBeginOf2018}
|
||||
|
||||
object En extends Lang {
|
||||
|
||||
@@ -81,7 +81,7 @@ object En extends Lang {
|
||||
s" in <b>${bookingData.clinicId.name}</b> clinic" +
|
||||
s" of the <b>${bookingData.cityId.name}</b> city." +
|
||||
s"\nDesired dates: <b>${formatDate(bookingData.dateFrom, locale)}</b> -> <b>${formatDate(bookingData.dateTo, locale)}</b>" +
|
||||
s"\nTime: <b>${timeOfDay(bookingData.timeOfDay)}</b>" +
|
||||
s"\nTime: <b>${formatTime(bookingData.timeFrom)} -> ${formatTime(bookingData.timeTo)}</b>" +
|
||||
s"\n\n<b>➡</b> Now choose your action"
|
||||
|
||||
override def noTermsFound: String =
|
||||
@@ -135,7 +135,7 @@ object En extends Lang {
|
||||
s"""<b>➡</b> Are you sure want to deactivate monitoring?
|
||||
|
|
||||
|📅 <b>${formatDate(monitoring.dateFrom, locale)}</b> -> <b>${formatDate(monitoring.dateTo, locale)}</b>
|
||||
|⏱ <b>${timeOfDay(monitoring.timeOfDay)}</b>
|
||||
|⏱ <b>${formatTime(monitoring.timeFrom)}</b> -> <b>${formatTime(monitoring.timeTo)}</b>
|
||||
|${capitalizeFirstLetter(doctor)}: ${monitoring.doctorName}
|
||||
|${capitalizeFirstLetter(service)}: ${monitoring.serviceName}
|
||||
|${capitalizeFirstLetter(clinic)}: ${monitoring.clinicName}""".stripMargin
|
||||
@@ -249,7 +249,7 @@ object En extends Lang {
|
||||
|
||||
override def monitoringEntry(monitoring: Monitoring, page: Int, index: Int): String =
|
||||
s"""📅 <b>${formatDate(monitoring.dateFrom, locale)}</b> -> <b>${formatDate(monitoring.dateTo, locale)}</b>
|
||||
|⏱ <b>${timeOfDay(monitoring.timeOfDay)}</b>
|
||||
|⏱ <b>${formatTime(monitoring.timeFrom)}</b> -> <b>${formatTime(monitoring.timeTo)}</b>
|
||||
|${capitalizeFirstLetter(doctor)}: ${monitoring.doctorName}
|
||||
|${capitalizeFirstLetter(service)}: ${monitoring.serviceName}
|
||||
|${capitalizeFirstLetter(clinic)}: ${monitoring.clinicName}
|
||||
@@ -286,7 +286,7 @@ object En extends Lang {
|
||||
s"""❗ Nothing was found by your monitoring. Monitoring has been <b>disabled</b> as outdated.
|
||||
|
|
||||
|📅 <b>${formatDate(monitoring.dateFrom, locale)}</b> -> <b>${formatDate(monitoring.dateTo, locale)}</b>
|
||||
|⏱ <b>${timeOfDay(monitoring.timeOfDay)}</b>
|
||||
|⏱ <b>${formatTime(monitoring.timeFrom)}</b> -> <b>${formatTime(monitoring.timeTo)}</b>
|
||||
|${capitalizeFirstLetter(doctor)}: ${monitoring.doctorName}
|
||||
|${capitalizeFirstLetter(service)}: ${monitoring.serviceName}
|
||||
|${capitalizeFirstLetter(clinic)}: ${monitoring.clinicName}
|
||||
@@ -342,8 +342,6 @@ object En extends Lang {
|
||||
|
||||
override def bugHasBeenCreated(bugId: Long): String = s"✅ Thank you for submitting bug <b>#$bugId</b>!"
|
||||
|
||||
override def chooseTimeOfDay: String = "<b>➡</b> Please choose preferred time of day"
|
||||
|
||||
override def afterFive: String = "After 17:00"
|
||||
|
||||
override def nineToFive: String = "From 09:00 to 17:00"
|
||||
@@ -352,8 +350,6 @@ object En extends Lang {
|
||||
|
||||
override def allDay: String = "All day"
|
||||
|
||||
override def preferredTimeIs(time: Int): String = s"⏱ Preferred time is ${timeOfDay(time)}"
|
||||
|
||||
override def deleteAccount: String = "➖ Delete account"
|
||||
|
||||
override def addAccount: String = "➕ Add account"
|
||||
@@ -367,4 +363,12 @@ object En extends Lang {
|
||||
|<b>➡</b> Please choose an <b>action</b> or select <b>account</b>""".stripMargin
|
||||
|
||||
override def moreParameters: String = "🛠 More parameters"
|
||||
|
||||
override def chooseTimeFrom: String = "<b>➡</b> Please choose time from"
|
||||
|
||||
override def chooseTimeTo: String = "<b>➡</b> Please choose time to"
|
||||
|
||||
override def timeFromIs(timeFrom: LocalTime): String = s"⏱ Time from is ${formatTime(timeFrom)}"
|
||||
|
||||
override def timeToIs(timeTo: LocalTime): String = s"⏱ Date to is ${formatTime(timeTo)}"
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
package com.lbs.server.lang
|
||||
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.{LocalTime, ZonedDateTime}
|
||||
import java.util.Locale
|
||||
|
||||
import com.lbs.api.json.model.{AvailableVisitsTermPresentation, HistoricVisit, ReservedVisit, ValuationsResponse}
|
||||
@@ -50,13 +50,6 @@ trait Lang {
|
||||
|
||||
def label: String
|
||||
|
||||
val timeOfDay = Map(
|
||||
0 -> allDay,
|
||||
1 -> beforeNine,
|
||||
2 -> nineToFive,
|
||||
3 -> afterFive
|
||||
)
|
||||
|
||||
protected def capitalizeFirstLetter(str: String): String = {
|
||||
val fistCapitalLetter = str.head.toTitleCase
|
||||
fistCapitalLetter + str.tail
|
||||
@@ -80,6 +73,10 @@ trait Lang {
|
||||
|
||||
def chooseDateTo: String
|
||||
|
||||
def chooseTimeFrom: String
|
||||
|
||||
def chooseTimeTo: String
|
||||
|
||||
def findTerms: String
|
||||
|
||||
def modifyDate: String
|
||||
@@ -162,6 +159,10 @@ trait Lang {
|
||||
|
||||
def dateToIs(dateTo: ZonedDateTime): String
|
||||
|
||||
def timeFromIs(timeFrom: LocalTime): String
|
||||
|
||||
def timeToIs(timeTo: LocalTime): String
|
||||
|
||||
def termEntry(term: AvailableVisitsTermPresentation, page: Int, index: Int): String
|
||||
|
||||
def termsHeader(page: Int, pages: Int): String
|
||||
@@ -224,8 +225,6 @@ trait Lang {
|
||||
|
||||
def enterIssueDetails: String
|
||||
|
||||
def chooseTimeOfDay: String
|
||||
|
||||
def afterFive: String
|
||||
|
||||
def nineToFive: String
|
||||
@@ -234,8 +233,6 @@ trait Lang {
|
||||
|
||||
def allDay: String
|
||||
|
||||
def preferredTimeIs(time: Int): String
|
||||
|
||||
def deleteAccount: String
|
||||
|
||||
def addAccount: String
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
*/
|
||||
package com.lbs.server.lang
|
||||
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.{LocalTime, ZonedDateTime}
|
||||
import java.util.Locale
|
||||
|
||||
import com.lbs.api.json.model.{AvailableVisitsTermPresentation, HistoricVisit, ReservedVisit, ValuationsResponse}
|
||||
import com.lbs.server.actor.Book
|
||||
import com.lbs.server.actor.StaticData.StaticDataConfig
|
||||
import com.lbs.server.repository.model.{Bug, Monitoring}
|
||||
import com.lbs.server.util.DateTimeUtil.{formatDate, formatDateTime, minutesSinceBeginOf2018}
|
||||
import com.lbs.server.util.DateTimeUtil.{formatDate, formatDateTime, formatTime, minutesSinceBeginOf2018}
|
||||
|
||||
object Ua extends Lang {
|
||||
|
||||
@@ -81,7 +81,7 @@ object Ua extends Lang {
|
||||
s" в <b>${bookingData.clinicId.name}</b> клініці" +
|
||||
s" міста <b>${bookingData.cityId.name}</b>." +
|
||||
s"\nБажані дати: <b>${formatDate(bookingData.dateFrom, locale)}</b> -> <b>${formatDate(bookingData.dateTo, locale)}</b>" +
|
||||
s"\nЧас: <b>${timeOfDay(bookingData.timeOfDay)}</b>" +
|
||||
s"\nЧас: <b>${formatTime(bookingData.timeFrom)}</b> -> <b>${formatTime(bookingData.timeTo)}</b>" +
|
||||
s"\n\n<b>➡</b> Тепер оберіть наступну дію"
|
||||
|
||||
override def noTermsFound: String =
|
||||
@@ -135,7 +135,7 @@ object Ua extends Lang {
|
||||
s"""<b>➡</b> Ви впевнені, що хочете вимкнути моніторинг?
|
||||
|
|
||||
|📅 <b>${formatDate(monitoring.dateFrom, locale)}</b> -> <b>${formatDate(monitoring.dateTo, locale)}</b>
|
||||
|⏱ <b>${timeOfDay(monitoring.timeOfDay)}</b>
|
||||
|⏱ <b>${formatTime(monitoring.timeFrom)}</b> -> <b>${formatTime(monitoring.timeTo)}</b>
|
||||
|${capitalizeFirstLetter(doctor)}: ${monitoring.doctorName}
|
||||
|${capitalizeFirstLetter(service)}: ${monitoring.serviceName}
|
||||
|${capitalizeFirstLetter(clinic)}: ${monitoring.clinicName}""".stripMargin
|
||||
@@ -248,7 +248,7 @@ object Ua extends Lang {
|
||||
|
||||
override def monitoringEntry(monitoring: Monitoring, page: Int, index: Int): String =
|
||||
s"""📅 <b>${formatDate(monitoring.dateFrom, locale)}</b> -> <b>${formatDate(monitoring.dateTo, locale)}</b>
|
||||
|⏱ <b>${timeOfDay(monitoring.timeOfDay)}</b>
|
||||
|⏱ <b>${formatTime(monitoring.timeFrom)}</b> -> <b>${formatTime(monitoring.timeTo)}</b>
|
||||
|${capitalizeFirstLetter(doctor)}: ${monitoring.doctorName}
|
||||
|${capitalizeFirstLetter(service)}: ${monitoring.serviceName}
|
||||
|${capitalizeFirstLetter(clinic)}: ${monitoring.clinicName}
|
||||
@@ -285,7 +285,7 @@ object Ua extends Lang {
|
||||
s"""❗ Нічого не знайдено за вашим моніторингом. Моніторинг був <b>вимкнений</b> як застарілий.
|
||||
|
|
||||
|📅 <b>${formatDate(monitoring.dateFrom, locale)}</b> -> <b>${formatDate(monitoring.dateTo, locale)}</b>
|
||||
|⏱ <b>${timeOfDay(monitoring.timeOfDay)}</b>
|
||||
|⏱ <b>${formatTime(monitoring.timeFrom)}</b> -> <b>${formatTime(monitoring.timeTo)}</b>
|
||||
|${capitalizeFirstLetter(doctor)}: ${monitoring.doctorName}
|
||||
|${capitalizeFirstLetter(service)}: ${monitoring.serviceName}
|
||||
|${capitalizeFirstLetter(clinic)}: ${monitoring.clinicName}
|
||||
@@ -341,8 +341,6 @@ object Ua extends Lang {
|
||||
|
||||
override def bugHasBeenCreated(bugId: Long): String = s"✅ Дякуємо за відправлений баг <b>#$bugId</b>!"
|
||||
|
||||
override def chooseTimeOfDay: String = "<b>➡</b> Будь ласка, оберіть бажаний час"
|
||||
|
||||
override def afterFive: String = "Після 17:00"
|
||||
|
||||
override def nineToFive: String = "Від 09:00 до 17:00"
|
||||
@@ -351,8 +349,6 @@ object Ua extends Lang {
|
||||
|
||||
override def allDay: String = "Весь день"
|
||||
|
||||
override def preferredTimeIs(time: Int): String = s"⏱ Бажаний час ${timeOfDay(time)}"
|
||||
|
||||
override def deleteAccount: String = "➖ Видалити акаунт"
|
||||
|
||||
override def addAccount: String = "➕ Додати акаунт"
|
||||
@@ -366,4 +362,12 @@ object Ua extends Lang {
|
||||
|<b>➡</b> Будь ласка, оберіть <b>дію</b> або виберіть <b>акаунт</b>""".stripMargin
|
||||
|
||||
override def moreParameters: String = "🛠 Більше налаштувань"
|
||||
|
||||
override def chooseTimeFrom: String = "<b>➡</b> Будь ласка, виберіть початковий час"
|
||||
|
||||
override def chooseTimeTo: String = "<b>➡</b> Будь ласка, виберіть кінцевий час"
|
||||
|
||||
override def timeFromIs(timeFrom: LocalTime): String = s"⏱ Початковий час ${formatTime(timeFrom)}"
|
||||
|
||||
override def timeToIs(timeTo: LocalTime): String = s"⏱ Кінцевий час ${formatTime(timeTo)}"
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
package com.lbs.server.repository.model
|
||||
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.{LocalTime, ZonedDateTime}
|
||||
|
||||
import javax.persistence.{Access, AccessType, Column, Entity}
|
||||
|
||||
@@ -89,8 +89,12 @@ class Monitoring extends RecordId {
|
||||
var dateTo: ZonedDateTime = _
|
||||
|
||||
@BeanProperty
|
||||
@Column(name = "time_of_day", nullable = true)
|
||||
var timeOfDay: JInt = 0
|
||||
@Column(name = "time_from", nullable = false)
|
||||
var timeFrom: LocalTime = _
|
||||
|
||||
@BeanProperty
|
||||
@Column(name = "time_to", nullable = false)
|
||||
var timeTo: LocalTime = _
|
||||
|
||||
@BeanProperty
|
||||
@Column(nullable = false)
|
||||
@@ -108,7 +112,7 @@ class Monitoring extends RecordId {
|
||||
object Monitoring {
|
||||
def apply(userId: Long, accountId: Long, chatId: String, sourceSystemId: Long, cityId: Long, cityName: String, clinicId: Option[Long], clinicName: String,
|
||||
serviceId: Long, serviceName: String, doctorId: Option[Long], doctorName: String, dateFrom: ZonedDateTime,
|
||||
dateTo: ZonedDateTime, autobook: Boolean = false, created: ZonedDateTime = ZonedDateTime.now(), timeOfDay: Int,
|
||||
dateTo: ZonedDateTime, autobook: Boolean = false, created: ZonedDateTime = ZonedDateTime.now(), timeFrom: LocalTime, timeTo: LocalTime,
|
||||
active: Boolean = true): Monitoring = {
|
||||
val monitoring = new Monitoring
|
||||
monitoring.userId = userId
|
||||
@@ -125,7 +129,8 @@ object Monitoring {
|
||||
monitoring.doctorName = doctorName
|
||||
monitoring.dateFrom = dateFrom
|
||||
monitoring.dateTo = dateTo
|
||||
monitoring.timeOfDay = timeOfDay
|
||||
monitoring.timeFrom = timeFrom
|
||||
monitoring.timeTo = timeTo
|
||||
monitoring.autobook = autobook
|
||||
monitoring.created = created
|
||||
monitoring.active = active
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
package com.lbs.server.service
|
||||
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.{LocalTime, ZonedDateTime}
|
||||
|
||||
import com.lbs.api.LuxmedApi
|
||||
import com.lbs.api.json.model._
|
||||
@@ -73,13 +73,19 @@ class ApiService extends SessionSupport {
|
||||
}
|
||||
|
||||
def getAvailableTerms(accountId: Long, cityId: Long, clinicId: Option[Long], serviceId: Long, doctorId: Option[Long],
|
||||
fromDate: ZonedDateTime = ZonedDateTime.now(), toDate: Option[ZonedDateTime] = None, timeOfDay: Int = 0,
|
||||
fromDate: ZonedDateTime = ZonedDateTime.now(), toDate: Option[ZonedDateTime] = None, timeFrom: LocalTime, timeTo: LocalTime,
|
||||
languageId: Long = 10, findFirstFreeTerm: Boolean = false): Either[Throwable, List[AvailableVisitsTermPresentation]] =
|
||||
getDefaultPayer(accountId, cityId, clinicId, serviceId).flatMap {
|
||||
case Some(payerId) =>
|
||||
withSession(accountId) { session =>
|
||||
LuxmedApi.availableTerms(session.accessToken, session.tokenType, payerId.id, cityId, clinicId, serviceId, doctorId,
|
||||
fromDate, toDate, timeOfDay, languageId, findFirstFreeTerm).map(_.availableVisitsTermPresentation)
|
||||
val termsEither = LuxmedApi.availableTerms(session.accessToken, session.tokenType, payerId.id, cityId, clinicId, serviceId, doctorId,
|
||||
fromDate, toDate, languageId = languageId, findFirstFreeTerm = findFirstFreeTerm).map(_.availableVisitsTermPresentation)
|
||||
termsEither.map { terms =>
|
||||
terms.filter { term =>
|
||||
val time = term.visitDate.startDateTime.toLocalTime
|
||||
time == timeFrom || time == timeTo || (time.isAfter(timeFrom) && time.isBefore(timeTo))
|
||||
}
|
||||
}
|
||||
}
|
||||
case None => sys.error(s"Can't determine payer id by user: $accountId, city: $cityId, clinic: $clinicId, service: $serviceId")
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ class MonitoringService extends Logger {
|
||||
debug(s"Looking for available terms. Monitoring [#${monitoring.recordId}]")
|
||||
val dateFrom = optimizeDateFrom(monitoring.dateFrom)
|
||||
val termsEither = apiService.getAvailableTerms(monitoring.accountId, monitoring.cityId, monitoring.clinicId, monitoring.serviceId,
|
||||
monitoring.doctorId, dateFrom, Some(monitoring.dateTo))
|
||||
monitoring.doctorId, dateFrom, Some(monitoring.dateTo), timeFrom = monitoring.timeFrom, timeTo = monitoring.timeTo)
|
||||
termsEither match {
|
||||
case Right(terms) =>
|
||||
if (terms.nonEmpty) {
|
||||
@@ -219,7 +219,7 @@ class MonitoringService extends Logger {
|
||||
monitoringMaybe match {
|
||||
case Some(monitoring) =>
|
||||
val termsEither = apiService.getAvailableTerms(monitoring.accountId, monitoring.cityId, monitoring.clinicId, monitoring.serviceId,
|
||||
monitoring.doctorId, monitoring.dateFrom, Some(monitoring.dateTo))
|
||||
monitoring.doctorId, monitoring.dateFrom, Some(monitoring.dateTo), timeFrom = monitoring.timeFrom, timeTo = monitoring.timeTo)
|
||||
termsEither match {
|
||||
case Right(terms) =>
|
||||
val termMaybe = terms.find(term => term.scheduleId == scheduleId && minutesSinceBeginOf2018(term.visitDate.startDateTime) == time)
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
package com.lbs.server
|
||||
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.{ZoneId, ZonedDateTime}
|
||||
import java.time.{LocalTime, ZoneId, ZonedDateTime}
|
||||
import java.util.Locale
|
||||
|
||||
import com.lbs.api.json.model._
|
||||
import com.lbs.bot.model.{Command, Message}
|
||||
import com.lbs.bot.model.Command
|
||||
import com.lbs.common.ModelConverters
|
||||
import com.lbs.server.actor.Book.BookingData
|
||||
import com.lbs.server.actor.Login.UserId
|
||||
@@ -62,7 +62,8 @@ package object util {
|
||||
doctorName = bookingData.doctorId.name,
|
||||
dateFrom = bookingData.dateFrom,
|
||||
dateTo = bookingData.dateTo,
|
||||
timeOfDay = bookingData.timeOfDay,
|
||||
timeFrom = bookingData.timeFrom,
|
||||
timeTo = bookingData.timeTo,
|
||||
autobook = bookingData.autobook
|
||||
)
|
||||
}
|
||||
@@ -143,10 +144,14 @@ package object util {
|
||||
object DateTimeUtil {
|
||||
private val DateFormat: Locale => DateTimeFormatter = locale => DateTimeFormatter.ofPattern("dd MMM yyyy", locale)
|
||||
|
||||
private val TimeFormat: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm")
|
||||
|
||||
private val DateTimeFormat: Locale => DateTimeFormatter = locale => DateTimeFormatter.ofPattern("EEE',' dd MMM yyyy',' HH:mm", locale)
|
||||
|
||||
def formatDate(date: ZonedDateTime, locale: Locale): String = date.format(DateFormat(locale))
|
||||
|
||||
def formatTime(time: LocalTime): String = time.format(TimeFormat)
|
||||
|
||||
def formatDateTime(date: ZonedDateTime, locale: Locale): String = date.format(DateTimeFormat(locale))
|
||||
|
||||
private val EpochMinutesTillBeginOf2018: Long = epochMinutes(ZonedDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()))
|
||||
|
||||
Reference in New Issue
Block a user