create a reminder for a booked appointment

This commit is contained in:
Eugene Zadyra
2022-08-10 23:29:51 +02:00
parent e870e404e1
commit a735271263
14 changed files with 398 additions and 23 deletions

View File

@@ -0,0 +1,75 @@
databaseChangeLog:
- changeSet:
id: 06
author: dyrkin
preConditions:
onFail: MARK_RAN
not:
tableExists:
tableName: reminder
changes:
- createTable:
tableName: reminder
columns:
- column:
autoIncrement: true
constraints:
primaryKey: true
primaryKeyName: bug_pkey
name: record_id
type: BIGSERIAL
- column:
constraints:
nullable: false
name: user_id
type: BIGINT
- column:
constraints:
nullable: false
name: account_id
type: BIGINT
- column:
constraints:
nullable: false
name: chat_id
type: BIGINT
- column:
constraints:
nullable: false
name: source_system_id
type: BIGINT
- column:
constraints:
nullable: false
name: city_name
type: VARCHAR(255)
- column:
constraints:
nullable: false
name: clinic_name
type: VARCHAR(255)
- column:
constraints:
nullable: false
name: service_name
type: VARCHAR(255)
- column:
constraints:
nullable: false
name: doctor_name
type: VARCHAR(255)
- column:
constraints:
nullable: false
name: appointment_time
type: TIME WITHOUT TIME ZONE
- column:
constraints:
nullable: true
name: remind_at_time
type: TIME WITHOUT TIME ZONE
- column:
constraints:
nullable: true
name: active
type: BOOLEAN

View File

@@ -17,3 +17,6 @@ databaseChangeLog:
- include: - include:
file: changelog/05-drop-bugs-table.yml file: changelog/05-drop-bugs-table.yml
relativeToChangelogFile: true relativeToChangelogFile: true
- include:
file: changelog/06-reminders.yml
relativeToChangelogFile: true

View File

@@ -7,7 +7,7 @@ import com.lbs.bot.telegram.TelegramBot
import com.lbs.server.conversation._ import com.lbs.server.conversation._
import com.lbs.server.lang.Localization import com.lbs.server.lang.Localization
import com.lbs.server.repository.model.Monitoring import com.lbs.server.repository.model.Monitoring
import com.lbs.server.service.{ApiService, DataService, MonitoringService} import com.lbs.server.service.{ApiService, DataService, MonitoringService, ReminderService}
import org.jasypt.util.text.{StrongTextEncryptor, TextEncryptor} import org.jasypt.util.text.{StrongTextEncryptor, TextEncryptor}
import org.springframework.beans.factory.annotation.{Autowired, Value} import org.springframework.beans.factory.annotation.{Autowired, Value}
import org.springframework.context.annotation.{Bean, Configuration} import org.springframework.context.annotation.{Bean, Configuration}
@@ -29,6 +29,9 @@ class BootConfig {
@Autowired @Autowired
private var monitoringService: MonitoringService = _ private var monitoringService: MonitoringService = _
@Autowired
private var reminderService: ReminderService = _
@Autowired @Autowired
private var localization: Localization = _ private var localization: Localization = _
@@ -123,8 +126,8 @@ class BootConfig {
userId => userId =>
new Chat( new Chat(
userId, userId,
dataService,
monitoringService, monitoringService,
reminderService,
bookFactory, bookFactory,
helpFactory, helpFactory,
monitoringsFactory, monitoringsFactory,

View File

@@ -5,7 +5,7 @@ import com.lbs.bot.model.Command
import com.lbs.server.conversation.Chat._ import com.lbs.server.conversation.Chat._
import com.lbs.server.conversation.Login.UserId import com.lbs.server.conversation.Login.UserId
import com.lbs.server.conversation.base.{Conversation, Interactional} import com.lbs.server.conversation.base.{Conversation, Interactional}
import com.lbs.server.service.{DataService, MonitoringService} import com.lbs.server.service.{MonitoringService, ReminderService}
import com.lbs.server.util.MessageExtractors._ import com.lbs.server.util.MessageExtractors._
import com.typesafe.scalalogging.StrictLogging import com.typesafe.scalalogging.StrictLogging
@@ -13,8 +13,8 @@ import scala.util.matching.Regex
class Chat( class Chat(
val userId: UserId, val userId: UserId,
dataService: DataService,
monitoringService: MonitoringService, monitoringService: MonitoringService,
reminderService: ReminderService,
bookingFactory: UserIdTo[Book], bookingFactory: UserIdTo[Book],
helpFactory: UserIdTo[Help], helpFactory: UserIdTo[Help],
monitoringsFactory: UserIdTo[Monitorings], monitoringsFactory: UserIdTo[Monitorings],
@@ -127,12 +127,12 @@ class Chat(
case Msg(cmd @ TextCommand("/accounts"), _) => case Msg(cmd @ TextCommand("/accounts"), _) =>
self ! cmd self ! cmd
goto(accountChat) goto(accountChat)
case Msg(TextCommand(ReserveTerm(monitoringIdStr, scheduleIdStr, timeStr)), _) => case Msg(TextCommand(ReserveTermRegex(LongString(monitoringId), LongString(scheduleId), LongString(time))), _) =>
val monitoringId = monitoringIdStr.toLong
val scheduleId = scheduleIdStr.toLong
val time = timeStr.toLong
monitoringService.bookAppointmentByScheduleId(userId.accountId, monitoringId, scheduleId, time) monitoringService.bookAppointmentByScheduleId(userId.accountId, monitoringId, scheduleId, time)
stay() stay()
case Msg(CallbackCommand(RemindRegexp(LongString(reminderId), LongString(time))), _) =>
reminderService.activateReminder(userId.accountId, reminderId, time)
stay()
case Msg(cmd: Command, _) => case Msg(cmd: Command, _) =>
interactional ! cmd interactional ! cmd
stay() stay()
@@ -151,5 +151,6 @@ class Chat(
} }
object Chat { object Chat {
val ReserveTerm: Regex = s"/reserve_(\\d+)_(\\d+)_(\\d+)".r val ReserveTermRegex: Regex = "/reserve_(\\d+)_(\\d+)_(\\d+)".r
val RemindRegexp: Regex = "remind_at_(\\d+)_(\\d+)".r
} }

View File

@@ -3,7 +3,7 @@ package com.lbs.server.lang
import com.lbs.api.json.model.{Event, TermExt} import com.lbs.api.json.model.{Event, TermExt}
import com.lbs.server.conversation.Book import com.lbs.server.conversation.Book
import com.lbs.server.conversation.StaticData.StaticDataConfig import com.lbs.server.conversation.StaticData.StaticDataConfig
import com.lbs.server.repository.model.Monitoring import com.lbs.server.repository.model.{Monitoring, Reminder}
import com.lbs.server.util.DateTimeUtil._ import com.lbs.server.util.DateTimeUtil._
import java.time.{LocalDateTime, LocalTime} import java.time.{LocalDateTime, LocalTime}
@@ -173,7 +173,7 @@ object En extends Lang {
override def help: String = override def help: String =
s""" Non official bot for <b>Portal Pacjenta LUX MED (v.${Lang.version})</b>. s""" Non official bot for <b>Portal Pacjenta LUX MED (v.${Lang.version})</b>.
|It can help you to book a visit to a doctor, create term monitoring, view upcoming appointments and visit history. |The bot can help you book a visit to a doctor, create term monitorings, view upcoming appointments and visit history.
| |
|<b>➡</b> Supported commands |<b>➡</b> Supported commands
|/book - reserve a visit, or create a monitoring |/book - reserve a visit, or create a monitoring
@@ -377,4 +377,17 @@ object En extends Lang {
override def canNotDetectPayer(error: String): String = s"Can't determine payer. Reason: $error" override def canNotDetectPayer(error: String): String = s"Can't determine payer. Reason: $error"
override def pleaseChoosePayer: String = "<b>➡</b> Can't determine default payer. Please choose one" override def pleaseChoosePayer: String = "<b>➡</b> Can't determine default payer. Please choose one"
override def youHaveAppointmentAt(reminder: Reminder): String =
s"""👍 You have an appointment at ⏱ <b>${formatTime(reminder.appointmentTime.toLocalTime)}</b>!
|
|${capitalize(doctor)}: ${reminder.doctorName}
|${capitalize(service)}: ${reminder.serviceName}
|${capitalize(clinic)}: ${reminder.clinicName}
|${capitalize(city)}: ${reminder.cityName}""".stripMargin
override def remindAt(time: LocalDateTime): String = s"⏱ Remind at ${formatTime(time.toLocalTime)}"
override def appointmentIsOutdated(appointmentTime: LocalDateTime): String =
s"Your appointment has already taken place at ${formatDateTime(appointmentTime, locale)}"
} }

View File

@@ -3,7 +3,7 @@ package com.lbs.server.lang
import com.lbs.api.json.model.{Event, TermExt} import com.lbs.api.json.model.{Event, TermExt}
import com.lbs.server.conversation.Book.BookingData import com.lbs.server.conversation.Book.BookingData
import com.lbs.server.conversation.StaticData.StaticDataConfig import com.lbs.server.conversation.StaticData.StaticDataConfig
import com.lbs.server.repository.model.Monitoring import com.lbs.server.repository.model.{Monitoring, Reminder}
import java.time.{LocalDateTime, LocalTime} import java.time.{LocalDateTime, LocalTime}
import java.util.Locale import java.util.Locale
@@ -235,4 +235,10 @@ trait Lang {
def pleaseChooseAccount(currentAccountName: String): String def pleaseChooseAccount(currentAccountName: String): String
def accountSwitched(username: String): String def accountSwitched(username: String): String
def youHaveAppointmentAt(reminder: Reminder): String
def remindAt(time: LocalDateTime): String
def appointmentIsOutdated(appointmentTime: LocalDateTime): String
} }

View File

@@ -3,7 +3,7 @@ package com.lbs.server.lang
import com.lbs.api.json.model.{Event, TermExt} import com.lbs.api.json.model.{Event, TermExt}
import com.lbs.server.conversation.Book import com.lbs.server.conversation.Book
import com.lbs.server.conversation.StaticData.StaticDataConfig import com.lbs.server.conversation.StaticData.StaticDataConfig
import com.lbs.server.repository.model.Monitoring import com.lbs.server.repository.model.{Monitoring, Reminder}
import com.lbs.server.util.DateTimeUtil._ import com.lbs.server.util.DateTimeUtil._
import java.time.{LocalDateTime, LocalTime} import java.time.{LocalDateTime, LocalTime}
@@ -379,4 +379,17 @@ object Pl extends Lang {
override def canNotDetectPayer(error: String): String = s"Nie udało się ustalić płatnika. Powód: $error" override def canNotDetectPayer(error: String): String = s"Nie udało się ustalić płatnika. Powód: $error"
override def pleaseChoosePayer: String = "<b>➡</b> Nie udało się ustalić domyślnego płatnika, wybierz jakiegoś." override def pleaseChoosePayer: String = "<b>➡</b> Nie udało się ustalić domyślnego płatnika, wybierz jakiegoś."
override def youHaveAppointmentAt(reminder: Reminder): String =
s"""👍 Macie wizytę o ⏱ <b>${formatTime(reminder.appointmentTime.toLocalTime)}</b>!
|
|${capitalize(doctor)}: ${reminder.doctorName}
|${capitalize(service)}: ${reminder.serviceName}
|${capitalize(clinic)}: ${reminder.clinicName}
|${capitalize(city)}: ${reminder.cityName}""".stripMargin
override def remindAt(time: LocalDateTime): String = s"⏱ Przypomnij o ${formatTime(time.toLocalTime)}"
override def appointmentIsOutdated(appointmentTime: LocalDateTime): String =
s"Twoja wizyta już się odbyła o godzine ${formatDateTime(appointmentTime, locale)}"
} }

View File

@@ -3,7 +3,7 @@ package com.lbs.server.lang
import com.lbs.api.json.model.{Event, TermExt} import com.lbs.api.json.model.{Event, TermExt}
import com.lbs.server.conversation.Book import com.lbs.server.conversation.Book
import com.lbs.server.conversation.StaticData.StaticDataConfig import com.lbs.server.conversation.StaticData.StaticDataConfig
import com.lbs.server.repository.model.Monitoring import com.lbs.server.repository.model.{Monitoring, Reminder}
import com.lbs.server.util.DateTimeUtil._ import com.lbs.server.util.DateTimeUtil._
import java.time.{LocalDateTime, LocalTime} import java.time.{LocalDateTime, LocalTime}
@@ -378,4 +378,17 @@ object Ua extends Lang {
override def pleaseChoosePayer: String = override def pleaseChoosePayer: String =
"<b>➡</b> Не можу визначити платника за замовчуванням. Будь ласка, виберіть платника" "<b>➡</b> Не можу визначити платника за замовчуванням. Будь ласка, виберіть платника"
override def youHaveAppointmentAt(reminder: Reminder): String =
s"""👍 У вас є візит о ⏱ <b>${formatTime(reminder.appointmentTime.toLocalTime)}</b>!
|
|${capitalize(doctor)}: ${reminder.doctorName}
|${capitalize(service)}: ${reminder.serviceName}
|${capitalize(clinic)}: ${reminder.clinicName}
|${capitalize(city)}: ${reminder.cityName}""".stripMargin
override def remindAt(time: LocalDateTime): String = s"⏱ Remind at ${formatTime(time.toLocalTime)}"
override def appointmentIsOutdated(appointmentTime: LocalDateTime): String =
s"Your appointment has already taken place at ${formatDateTime(appointmentTime, locale)}"
} }

View File

@@ -1,6 +1,6 @@
package com.lbs.server.repository package com.lbs.server.repository
import com.lbs.server.repository.model.{CityHistory, ClinicHistory, Credentials, DoctorHistory, JLong, Monitoring, ServiceHistory, Settings, Source, SystemUser} import com.lbs.server.repository.model.{CityHistory, ClinicHistory, Credentials, DoctorHistory, JLong, Monitoring, Reminder, ServiceHistory, Settings, Source, SystemUser}
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
@@ -95,6 +95,15 @@ class DataRepository(@Autowired em: EntityManager) {
.toSeq .toSeq
} }
def getActiveReminders: Seq[Reminder] = {
em.createQuery(
"""select reminder from Reminder reminder where reminder.active = true""".stripMargin,
classOf[Reminder]
).getResultList
.asScala
.toSeq
}
def getActiveMonitoringsCount(accountId: Long): JLong = { def getActiveMonitoringsCount(accountId: Long): JLong = {
em.createQuery( em.createQuery(
"""select count(monitoring) from Monitoring monitoring where monitoring.active = true """select count(monitoring) from Monitoring monitoring where monitoring.active = true
@@ -177,6 +186,18 @@ class DataRepository(@Autowired em: EntityManager) {
.headOption .headOption
} }
def findReminder(accountId: Long, reminderId: Long): Option[Reminder] = {
em.createQuery(
"""select reminder from Reminder reminder where reminder.accountId = :accountId
| and reminder.recordId = :reminderId""".stripMargin,
classOf[Reminder]
).setParameter("accountId", accountId)
.setParameter("reminderId", reminderId)
.getResultList
.asScala
.headOption
}
def findSettings(userId: Long): Option[Settings] = { def findSettings(userId: Long): Option[Settings] = {
em.createQuery("select settings from Settings settings where settings.userId = :userId", classOf[Settings]) em.createQuery("select settings from Settings settings where settings.userId = :userId", classOf[Settings])
.setParameter("userId", userId) .setParameter("userId", userId)

View File

@@ -0,0 +1,83 @@
package com.lbs.server.repository.model
import java.time.LocalDateTime
import javax.persistence.{Access, AccessType, Column, Entity}
import scala.beans.BeanProperty
@Entity
@Access(AccessType.FIELD)
class Reminder extends RecordId {
@BeanProperty
@Column(name = "user_id", nullable = false)
var userId: JLong = _
@BeanProperty
@Column(name = "account_id", nullable = false)
var accountId: JLong = _
@BeanProperty
@Column(name = "chat_id", nullable = false)
var chatId: String = _
@BeanProperty
@Column(name = "source_system_id", nullable = false)
var sourceSystemId: JLong = _
@BeanProperty
@Column(name = "city_name", nullable = false)
var cityName: String = _
@BeanProperty
@Column(name = "clinic_name", nullable = false)
var clinicName: String = _
@BeanProperty
@Column(name = "service_name", nullable = false)
var serviceName: String = _
@BeanProperty
@Column(name = "doctor_name", nullable = false)
var doctorName: String = _
@BeanProperty
@Column(name = "appointment_time", nullable = false)
var appointmentTime: LocalDateTime = _
@BeanProperty
@Column(name = "remind_at_time", nullable = true)
var remindAt: LocalDateTime = _
@BeanProperty
@Column(nullable = false)
var active: Boolean = false
}
object Reminder {
def apply(
userId: Long,
accountId: Long,
chatId: String,
sourceSystemId: Long,
cityName: String,
clinicName: String,
serviceName: String,
doctorName: String,
appointmentTime: LocalDateTime,
remindAt: LocalDateTime,
active: Boolean
): Reminder = {
val reminder = new Reminder
reminder.userId = userId
reminder.accountId = accountId
reminder.chatId = chatId
reminder.sourceSystemId = sourceSystemId
reminder.cityName = cityName
reminder.clinicName = clinicName
reminder.serviceName = serviceName
reminder.doctorName = doctorName
reminder.appointmentTime = appointmentTime
reminder.remindAt = remindAt
reminder.active = active
reminder
}
}

View File

@@ -48,6 +48,15 @@ class DataService {
dataRepository.saveEntity(monitoring) dataRepository.saveEntity(monitoring)
} }
@Transactional
def saveReminder(reminder: Reminder): Reminder = {
dataRepository.saveEntity(reminder)
}
def getActiveReminders: Seq[Reminder] = {
dataRepository.getActiveReminders
}
def getActiveMonitorings: Seq[Monitoring] = { def getActiveMonitorings: Seq[Monitoring] = {
dataRepository.getActiveMonitorings dataRepository.getActiveMonitorings
} }
@@ -76,6 +85,10 @@ class DataService {
dataRepository.findMonitoring(accountId, monitoringId) dataRepository.findMonitoring(accountId, monitoringId)
} }
def findReminder(accountId: Long, reminderId: Long): Option[Reminder] = {
dataRepository.findReminder(accountId, reminderId)
}
def findSettings(userId: Long): Option[Settings] = { def findSettings(userId: Long): Option[Settings] = {
dataRepository.findSettings(userId) dataRepository.findSettings(userId)
} }

View File

@@ -2,8 +2,8 @@ package com.lbs.server.service
import com.lbs.api.exception.InvalidLoginOrPasswordException import com.lbs.api.exception.InvalidLoginOrPasswordException
import com.lbs.api.json.model._ import com.lbs.api.json.model._
import com.lbs.bot.Bot import com.lbs.bot.model.{Button, MessageSource, MessageSourceSystem}
import com.lbs.bot.model.{MessageSource, MessageSourceSystem} import com.lbs.bot.{Bot, createInlineKeyboard}
import com.lbs.common.Scheduler import com.lbs.common.Scheduler
import com.lbs.server.lang.Localization import com.lbs.server.lang.Localization
import com.lbs.server.repository.model._ import com.lbs.server.repository.model._
@@ -13,7 +13,7 @@ import com.typesafe.scalalogging.StrictLogging
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import java.time.{LocalDateTime, ZonedDateTime} import java.time.{LocalDateTime, ZoneId, ZonedDateTime}
import java.util.concurrent.ScheduledFuture import java.util.concurrent.ScheduledFuture
import javax.annotation.PostConstruct import javax.annotation.PostConstruct
import scala.collection.mutable import scala.collection.mutable
@@ -30,6 +30,8 @@ class MonitoringService extends StrictLogging {
@Autowired @Autowired
private var apiService: ApiService = _ private var apiService: ApiService = _
@Autowired @Autowired
private var reminderService: ReminderService = _
@Autowired
private var localization: Localization = _ private var localization: Localization = _
private var activeMonitorings = mutable.Map.empty[JLong, (Monitoring, ScheduledFuture[_])] private var activeMonitorings = mutable.Map.empty[JLong, (Monitoring, ScheduledFuture[_])]
@@ -195,8 +197,23 @@ class MonitoringService extends StrictLogging {
} yield response } yield response
bookingResult match { bookingResult match {
case Right(_) => case Right(_) =>
bot.sendMessage(monitoring.source, lang(monitoring.userId).appointmentIsBooked(term, monitoring))
deactivateMonitoring(monitoring.accountId, monitoring.recordId) deactivateMonitoring(monitoring.accountId, monitoring.recordId)
val reminder = reminderService.createInactiveReminder((term.term, monitoring).mapTo[Reminder])
val remind1h = term.term.dateTimeFrom.get.minusHours(1)
val remind1hMillis = remind1h.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli
val remind2h = term.term.dateTimeFrom.get.minusHours(2)
val remind2hMillis = remind2h.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli
val messages = lang(monitoring.userId)
bot.sendMessage(
monitoring.source,
messages.appointmentIsBooked(term, monitoring),
inlineKeyboard = createInlineKeyboard(
Seq(
Button(messages.remindAt(remind1h), s"remind_at_${reminder.recordId}_$remind1hMillis"),
Button(messages.remindAt(remind2h), s"remind_at_${reminder.recordId}_$remind2hMillis")
)
)
)
case Left(ex) => case Left(ex) =>
logger.error(s"Unable to book appointment by monitoring [${monitoring.recordId}]", ex) logger.error(s"Unable to book appointment by monitoring [${monitoring.recordId}]", ex)
} }
@@ -206,7 +223,7 @@ class MonitoringService extends StrictLogging {
accountId: Long, accountId: Long,
xsrfToken: XsrfToken, xsrfToken: XsrfToken,
temporaryReservationId: Long, temporaryReservationId: Long,
fn: (Long) => Either[Throwable, T] fn: Long => Either[Throwable, T]
): Either[Throwable, T] = { ): Either[Throwable, T] = {
fn(accountId) match { fn(accountId) match {
case r @ Left(_) => case r @ Left(_) =>

View File

@@ -0,0 +1,94 @@
package com.lbs.server.service
import com.lbs.bot.Bot
import com.lbs.bot.model.{MessageSource, MessageSourceSystem}
import com.lbs.common.Scheduler
import com.lbs.server.lang.Localization
import com.lbs.server.repository.model._
import com.typesafe.scalalogging.StrictLogging
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.time.{Instant, LocalDateTime, ZoneId}
import javax.annotation.PostConstruct
import scala.concurrent.duration._
@Service
class ReminderService extends StrictLogging {
@Autowired
private var bot: Bot = _
@Autowired
private var dataService: DataService = _
@Autowired
private var localization: Localization = _
private val dbChecker = new Scheduler(1)
private def deactivateReminder(accountId: JLong, reminderId: JLong): Unit = {
dataService.findReminder(accountId, reminderId).foreach { reminder =>
reminder.active = false
dataService.saveReminder(reminder)
}
}
def remindUserAboutAppointment(reminder: Reminder): Unit = {
deactivateReminder(reminder.accountId, reminder.recordId)
val messages = lang(reminder.userId)
val message = messages.youHaveAppointmentAt(reminder)
bot.sendMessage(reminder.source, message)
}
private def checkReminders(): Unit = {
logger.debug(s"Looking for active reminders")
val activeReminders = dataService.getActiveReminders
logger.debug(s"Found [${activeReminders.size}] active reminders")
val now = LocalDateTime.now()
activeReminders.foreach {
case reminder if reminder.remindAt.isAfter(now) =>
logger.debug(s"Notifying user [${reminder.userId}] about appointment at [${reminder.appointmentTime}]")
remindUserAboutAppointment(reminder)
}
}
private def initializeDbChecker(): Unit = {
dbChecker.schedule(checkReminders(), 20.seconds)
}
def createInactiveReminder(reminder: Reminder): Reminder = {
reminder.active = false
dataService.saveReminder(reminder)
}
def activateReminder(accountId: Long, reminderId: Long, timeMillis: Long): Unit = {
val time = Instant.ofEpochMilli(timeMillis).atZone(ZoneId.systemDefault()).toLocalDateTime
val reminderMaybe = dataService.findReminder(accountId, reminderId)
reminderMaybe.foreach { reminder =>
if (reminder.appointmentTime.isBefore(time)) {
reminder.active = true
reminder.remindAt = time
dataService.saveReminder(reminder)
} else {
val messages = lang(reminder.userId)
val message = messages.appointmentIsOutdated(reminder.appointmentTime)
bot.sendMessage(reminder.source, message)
}
}
}
implicit class ReminderAsSource(reminder: Reminder) {
def source: MessageSource = MessageSource(MessageSourceSystem(reminder.sourceSystemId), reminder.chatId)
}
private def lang(userId: Long) = localization.lang(userId)
@PostConstruct
private def initialize(): Unit = {
initializeDbChecker()
}
}

View File

@@ -5,12 +5,12 @@ import com.lbs.bot.model.Command
import com.lbs.common.ModelConverters import com.lbs.common.ModelConverters
import com.lbs.server.conversation.Book.BookingData import com.lbs.server.conversation.Book.BookingData
import com.lbs.server.conversation.Login.UserId import com.lbs.server.conversation.Login.UserId
import com.lbs.server.repository.model.{History, Monitoring} import com.lbs.server.repository.model.{History, Monitoring, Reminder}
import java.time._ import java.time._
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import java.util.Locale import java.util.Locale
import scala.language.{higherKinds, implicitConversions} import scala.language.implicitConversions
import scala.util.Try import scala.util.Try
package object util { package object util {
@@ -109,6 +109,24 @@ package object util {
) )
} }
implicit val TermAndMonitoringToReminder: ObjectConverter[(Term, Monitoring), Reminder] =
(data: (Term, Monitoring)) => {
val (term, monitoring) = data
Reminder(
userId = monitoring.userId,
accountId = monitoring.accountId,
chatId = monitoring.chatId,
sourceSystemId = monitoring.sourceSystemId,
cityName = monitoring.cityName,
clinicName = monitoring.clinicName,
serviceName = monitoring.serviceName,
doctorName = monitoring.doctorName,
appointmentTime = term.dateTimeFrom.get,
remindAt = null,
active = false
)
}
implicit val HistoryToIdNameConverter: ObjectConverter[History, IdName] = implicit val HistoryToIdNameConverter: ObjectConverter[History, IdName] =
(history: History) => IdName(history.id, history.name) (history: History) => IdName(history.id, history.name)
} }
@@ -167,6 +185,8 @@ package object util {
def formatDateTime(date: LuxmedFunnyDateTime, locale: Locale): String = date.get.format(DateTimeFormat(locale)) def formatDateTime(date: LuxmedFunnyDateTime, locale: Locale): String = date.get.format(DateTimeFormat(locale))
def formatDateTime(date: LocalDateTime, locale: Locale): String = date.format(DateTimeFormat(locale))
private val EpochMinutesTillBeginOf2022: Long = epochMinutes(LocalDateTime.of(2022, 1, 1, 0, 0, 0, 0)) private val EpochMinutesTillBeginOf2022: Long = epochMinutes(LocalDateTime.of(2022, 1, 1, 0, 0, 0, 0))
def epochMinutes(time: LocalDateTime): Long = time.toInstant(ZonedDateTime.now().getOffset).getEpochSecond / 60 def epochMinutes(time: LocalDateTime): Long = time.toInstant(ZonedDateTime.now().getOffset).getEpochSecond / 60