diff --git a/server/src/main/resources/db/changelog/06-reminders.yml b/server/src/main/resources/db/changelog/06-reminders.yml new file mode 100644 index 0000000..b314ff1 --- /dev/null +++ b/server/src/main/resources/db/changelog/06-reminders.yml @@ -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 \ No newline at end of file diff --git a/server/src/main/resources/db/liquibase-changelog.yml b/server/src/main/resources/db/liquibase-changelog.yml index 26bbea4..990a67b 100644 --- a/server/src/main/resources/db/liquibase-changelog.yml +++ b/server/src/main/resources/db/liquibase-changelog.yml @@ -16,4 +16,7 @@ databaseChangeLog: relativeToChangelogFile: true - include: file: changelog/05-drop-bugs-table.yml - relativeToChangelogFile: true \ No newline at end of file + relativeToChangelogFile: true +- include: + file: changelog/06-reminders.yml + relativeToChangelogFile: true \ No newline at end of file diff --git a/server/src/main/scala/com/lbs/server/BootConfig.scala b/server/src/main/scala/com/lbs/server/BootConfig.scala index 681a34b..afbd749 100644 --- a/server/src/main/scala/com/lbs/server/BootConfig.scala +++ b/server/src/main/scala/com/lbs/server/BootConfig.scala @@ -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, diff --git a/server/src/main/scala/com/lbs/server/conversation/Chat.scala b/server/src/main/scala/com/lbs/server/conversation/Chat.scala index 65ca164..c0120d9 100644 --- a/server/src/main/scala/com/lbs/server/conversation/Chat.scala +++ b/server/src/main/scala/com/lbs/server/conversation/Chat.scala @@ -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 } 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 9baaa40..8d22143 100644 --- a/server/src/main/scala/com/lbs/server/lang/En.scala +++ b/server/src/main/scala/com/lbs/server/lang/En.scala @@ -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 Portal Pacjenta LUX MED (v.${Lang.version}). - |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. | | 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 = " Can't determine default payer. Please choose one" + + override def youHaveAppointmentAt(reminder: Reminder): String = + s"""👍 You have an appointment at ⏱ ${formatTime(reminder.appointmentTime.toLocalTime)}! + | + |${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)}" } 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 030083d..f500812 100644 --- a/server/src/main/scala/com/lbs/server/lang/Lang.scala +++ b/server/src/main/scala/com/lbs/server/lang/Lang.scala @@ -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 } diff --git a/server/src/main/scala/com/lbs/server/lang/Pl.scala b/server/src/main/scala/com/lbs/server/lang/Pl.scala index 1ea4885..561f23f 100644 --- a/server/src/main/scala/com/lbs/server/lang/Pl.scala +++ b/server/src/main/scala/com/lbs/server/lang/Pl.scala @@ -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 = " Nie udało się ustalić domyślnego płatnika, wybierz jakiegoś." + + override def youHaveAppointmentAt(reminder: Reminder): String = + s"""👍 Macie wizytę o ⏱ ${formatTime(reminder.appointmentTime.toLocalTime)}! + | + |${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)}" } 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 229b542..65f1cd7 100644 --- a/server/src/main/scala/com/lbs/server/lang/Ua.scala +++ b/server/src/main/scala/com/lbs/server/lang/Ua.scala @@ -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 = " Не можу визначити платника за замовчуванням. Будь ласка, виберіть платника" + + override def youHaveAppointmentAt(reminder: Reminder): String = + s"""👍 У вас є візит о ⏱ ${formatTime(reminder.appointmentTime.toLocalTime)}! + | + |${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)}" } diff --git a/server/src/main/scala/com/lbs/server/repository/DataRepository.scala b/server/src/main/scala/com/lbs/server/repository/DataRepository.scala index cc7bf8a..11c5bf4 100644 --- a/server/src/main/scala/com/lbs/server/repository/DataRepository.scala +++ b/server/src/main/scala/com/lbs/server/repository/DataRepository.scala @@ -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) diff --git a/server/src/main/scala/com/lbs/server/repository/model/Reminder.scala b/server/src/main/scala/com/lbs/server/repository/model/Reminder.scala new file mode 100644 index 0000000..cc783a9 --- /dev/null +++ b/server/src/main/scala/com/lbs/server/repository/model/Reminder.scala @@ -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 + } +} diff --git a/server/src/main/scala/com/lbs/server/service/DataService.scala b/server/src/main/scala/com/lbs/server/service/DataService.scala index f521792..ce43210 100644 --- a/server/src/main/scala/com/lbs/server/service/DataService.scala +++ b/server/src/main/scala/com/lbs/server/service/DataService.scala @@ -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) } 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 a4f43f3..6f434cc 100644 --- a/server/src/main/scala/com/lbs/server/service/MonitoringService.scala +++ b/server/src/main/scala/com/lbs/server/service/MonitoringService.scala @@ -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(_) => diff --git a/server/src/main/scala/com/lbs/server/service/ReminderService.scala b/server/src/main/scala/com/lbs/server/service/ReminderService.scala new file mode 100644 index 0000000..90c9da1 --- /dev/null +++ b/server/src/main/scala/com/lbs/server/service/ReminderService.scala @@ -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() + } +} diff --git a/server/src/main/scala/com/lbs/server/util/package.scala b/server/src/main/scala/com/lbs/server/util/package.scala index 4017b70..1320961 100644 --- a/server/src/main/scala/com/lbs/server/util/package.scala +++ b/server/src/main/scala/com/lbs/server/util/package.scala @@ -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