mirror of
https://github.com/dyrkin/luxmed-bot.git
synced 2025-12-21 13:23:05 +01:00
create a reminder for a booked appointment
This commit is contained in:
75
server/src/main/resources/db/changelog/06-reminders.yml
Normal file
75
server/src/main/resources/db/changelog/06-reminders.yml
Normal 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
|
||||
@@ -17,3 +17,6 @@ databaseChangeLog:
|
||||
- include:
|
||||
file: changelog/05-drop-bugs-table.yml
|
||||
relativeToChangelogFile: true
|
||||
- include:
|
||||
file: changelog/06-reminders.yml
|
||||
relativeToChangelogFile: true
|
||||
@@ -7,7 +7,7 @@ import com.lbs.bot.telegram.TelegramBot
|
||||
import com.lbs.server.conversation._
|
||||
import com.lbs.server.lang.Localization
|
||||
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.springframework.beans.factory.annotation.{Autowired, Value}
|
||||
import org.springframework.context.annotation.{Bean, Configuration}
|
||||
@@ -29,6 +29,9 @@ class BootConfig {
|
||||
@Autowired
|
||||
private var monitoringService: MonitoringService = _
|
||||
|
||||
@Autowired
|
||||
private var reminderService: ReminderService = _
|
||||
|
||||
@Autowired
|
||||
private var localization: Localization = _
|
||||
|
||||
@@ -123,8 +126,8 @@ class BootConfig {
|
||||
userId =>
|
||||
new Chat(
|
||||
userId,
|
||||
dataService,
|
||||
monitoringService,
|
||||
reminderService,
|
||||
bookFactory,
|
||||
helpFactory,
|
||||
monitoringsFactory,
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.lbs.bot.model.Command
|
||||
import com.lbs.server.conversation.Chat._
|
||||
import com.lbs.server.conversation.Login.UserId
|
||||
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.typesafe.scalalogging.StrictLogging
|
||||
|
||||
@@ -13,8 +13,8 @@ import scala.util.matching.Regex
|
||||
|
||||
class Chat(
|
||||
val userId: UserId,
|
||||
dataService: DataService,
|
||||
monitoringService: MonitoringService,
|
||||
reminderService: ReminderService,
|
||||
bookingFactory: UserIdTo[Book],
|
||||
helpFactory: UserIdTo[Help],
|
||||
monitoringsFactory: UserIdTo[Monitorings],
|
||||
@@ -127,12 +127,12 @@ class Chat(
|
||||
case Msg(cmd @ TextCommand("/accounts"), _) =>
|
||||
self ! cmd
|
||||
goto(accountChat)
|
||||
case Msg(TextCommand(ReserveTerm(monitoringIdStr, scheduleIdStr, timeStr)), _) =>
|
||||
val monitoringId = monitoringIdStr.toLong
|
||||
val scheduleId = scheduleIdStr.toLong
|
||||
val time = timeStr.toLong
|
||||
case Msg(TextCommand(ReserveTermRegex(LongString(monitoringId), LongString(scheduleId), LongString(time))), _) =>
|
||||
monitoringService.bookAppointmentByScheduleId(userId.accountId, monitoringId, scheduleId, time)
|
||||
stay()
|
||||
case Msg(CallbackCommand(RemindRegexp(LongString(reminderId), LongString(time))), _) =>
|
||||
reminderService.activateReminder(userId.accountId, reminderId, time)
|
||||
stay()
|
||||
case Msg(cmd: Command, _) =>
|
||||
interactional ! cmd
|
||||
stay()
|
||||
@@ -151,5 +151,6 @@ class 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
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.lbs.server.lang
|
||||
import com.lbs.api.json.model.{Event, TermExt}
|
||||
import com.lbs.server.conversation.Book
|
||||
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 java.time.{LocalDateTime, LocalTime}
|
||||
@@ -173,7 +173,7 @@ object En extends Lang {
|
||||
|
||||
override def help: String =
|
||||
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
|
||||
|/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 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)}"
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.lbs.server.lang
|
||||
import com.lbs.api.json.model.{Event, TermExt}
|
||||
import com.lbs.server.conversation.Book.BookingData
|
||||
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.util.Locale
|
||||
@@ -235,4 +235,10 @@ trait Lang {
|
||||
def pleaseChooseAccount(currentAccountName: String): String
|
||||
|
||||
def accountSwitched(username: String): String
|
||||
|
||||
def youHaveAppointmentAt(reminder: Reminder): String
|
||||
|
||||
def remindAt(time: LocalDateTime): String
|
||||
|
||||
def appointmentIsOutdated(appointmentTime: LocalDateTime): String
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.lbs.server.lang
|
||||
import com.lbs.api.json.model.{Event, TermExt}
|
||||
import com.lbs.server.conversation.Book
|
||||
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 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 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)}"
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.lbs.server.lang
|
||||
import com.lbs.api.json.model.{Event, TermExt}
|
||||
import com.lbs.server.conversation.Book
|
||||
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 java.time.{LocalDateTime, LocalTime}
|
||||
@@ -378,4 +378,17 @@ object Ua extends Lang {
|
||||
|
||||
override def pleaseChoosePayer: String =
|
||||
"<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)}"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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.stereotype.Repository
|
||||
|
||||
@@ -95,6 +95,15 @@ class DataRepository(@Autowired em: EntityManager) {
|
||||
.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 = {
|
||||
em.createQuery(
|
||||
"""select count(monitoring) from Monitoring monitoring where monitoring.active = true
|
||||
@@ -177,6 +186,18 @@ class DataRepository(@Autowired em: EntityManager) {
|
||||
.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] = {
|
||||
em.createQuery("select settings from Settings settings where settings.userId = :userId", classOf[Settings])
|
||||
.setParameter("userId", userId)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,15 @@ class DataService {
|
||||
dataRepository.saveEntity(monitoring)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
def saveReminder(reminder: Reminder): Reminder = {
|
||||
dataRepository.saveEntity(reminder)
|
||||
}
|
||||
|
||||
def getActiveReminders: Seq[Reminder] = {
|
||||
dataRepository.getActiveReminders
|
||||
}
|
||||
|
||||
def getActiveMonitorings: Seq[Monitoring] = {
|
||||
dataRepository.getActiveMonitorings
|
||||
}
|
||||
@@ -76,6 +85,10 @@ class DataService {
|
||||
dataRepository.findMonitoring(accountId, monitoringId)
|
||||
}
|
||||
|
||||
def findReminder(accountId: Long, reminderId: Long): Option[Reminder] = {
|
||||
dataRepository.findReminder(accountId, reminderId)
|
||||
}
|
||||
|
||||
def findSettings(userId: Long): Option[Settings] = {
|
||||
dataRepository.findSettings(userId)
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ package com.lbs.server.service
|
||||
|
||||
import com.lbs.api.exception.InvalidLoginOrPasswordException
|
||||
import com.lbs.api.json.model._
|
||||
import com.lbs.bot.Bot
|
||||
import com.lbs.bot.model.{MessageSource, MessageSourceSystem}
|
||||
import com.lbs.bot.model.{Button, MessageSource, MessageSourceSystem}
|
||||
import com.lbs.bot.{Bot, createInlineKeyboard}
|
||||
import com.lbs.common.Scheduler
|
||||
import com.lbs.server.lang.Localization
|
||||
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.stereotype.Service
|
||||
|
||||
import java.time.{LocalDateTime, ZonedDateTime}
|
||||
import java.time.{LocalDateTime, ZoneId, ZonedDateTime}
|
||||
import java.util.concurrent.ScheduledFuture
|
||||
import javax.annotation.PostConstruct
|
||||
import scala.collection.mutable
|
||||
@@ -30,6 +30,8 @@ class MonitoringService extends StrictLogging {
|
||||
@Autowired
|
||||
private var apiService: ApiService = _
|
||||
@Autowired
|
||||
private var reminderService: ReminderService = _
|
||||
@Autowired
|
||||
private var localization: Localization = _
|
||||
|
||||
private var activeMonitorings = mutable.Map.empty[JLong, (Monitoring, ScheduledFuture[_])]
|
||||
@@ -195,8 +197,23 @@ class MonitoringService extends StrictLogging {
|
||||
} yield response
|
||||
bookingResult match {
|
||||
case Right(_) =>
|
||||
bot.sendMessage(monitoring.source, lang(monitoring.userId).appointmentIsBooked(term, monitoring))
|
||||
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) =>
|
||||
logger.error(s"Unable to book appointment by monitoring [${monitoring.recordId}]", ex)
|
||||
}
|
||||
@@ -206,7 +223,7 @@ class MonitoringService extends StrictLogging {
|
||||
accountId: Long,
|
||||
xsrfToken: XsrfToken,
|
||||
temporaryReservationId: Long,
|
||||
fn: (Long) => Either[Throwable, T]
|
||||
fn: Long => Either[Throwable, T]
|
||||
): Either[Throwable, T] = {
|
||||
fn(accountId) match {
|
||||
case r @ Left(_) =>
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,12 @@ import com.lbs.bot.model.Command
|
||||
import com.lbs.common.ModelConverters
|
||||
import com.lbs.server.conversation.Book.BookingData
|
||||
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.format.DateTimeFormatter
|
||||
import java.util.Locale
|
||||
import scala.language.{higherKinds, implicitConversions}
|
||||
import scala.language.implicitConversions
|
||||
import scala.util.Try
|
||||
|
||||
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] =
|
||||
(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: LocalDateTime, locale: Locale): String = date.format(DateTimeFormat(locale))
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user