def choose_day(update, context): if update.message.text.isnumeric() or ('day' in context.user_data and 'wrong_hour' in context.user_data): if 'wrong_hour' in context.user_data: day = context.user_data['day'] del context.user_data['wrong_hour'] else: day = int(update.message.text) days = get_days(context.user_data['month']) if day in days: context.user_data['day'] = day chosen_day = date(YEAR, int(context.user_data['month']), int(context.user_data['day'])) user_reserves = sess.query(Reservation).filter( Reservation.user_id == update.message.chat_id, func.date(Reservation.day) == chosen_day, Reservation.is_expired != True, ).all() if user_reserves: update.message.reply_text( 'You already have the reservation on `' + chosen_day.strftime('%Y-%m-%d') + '`, you should cancel previous reservation if you want to change time', parse_mode=ParseMode.MARKDOWN ) choose_month(update, context) return DAY reserves = sess.query(Reservation).filter( func.date(Reservation.day) == chosen_day ).all() reserved_slots = [i.slot for i in reserves] reply_keyboard = get_hours(exclude=reserved_slots, for_keyboard=True) text = "Chosen date: `" + chosen_day.strftime('%Y-%m-%d') + "`\nChoose the hour, you want to reserve." if reserved_slots: text += "\n\nThese hours are already reserved:\n```\n" for slot in reserved_slots: text += slot + '\n' text += '```' reply_keyboard.insert(-1, ['Subscribe to waiting list']) update.message.reply_text( text, reply_markup=ReplyKeyboardMarkup(reply_keyboard, resize_keyboard=True, one_time_keyboard=True), parse_mode=ParseMode.MARKDOWN ) return HOUR else: context.user_data['wrong_day'] = True update.message.reply_text('Wrong date') if update.message.text == 'Back': reserve(update, context) return MONTH if update.message.text == 'Cancel': base.cancel(update, context) return ConversationHandler.END choose_month(update, context) return DAY
def choose_hour(update, context): i = 0 while i < len(HOURS): if update.message.text in HOURS[i]: check = sess.query(Reservation).filter_by( day=date(2019, int(userState[update.message.chat.id]['month']), int(userState[update.message.chat.id]['day'])), slot=update.message.text).first() if check is None: res = Reservation( user_id=update.message.chat.id, day=date(2019, int(userState[update.message.chat.id]['month']), int(userState[update.message.chat.id]['day'])), slot=update.message.text) sess.add(res) sess.commit() userState[update.message.chat.id] = {} update.message.reply_text('Time reserved successfully.') return True else: update.message.reply_text('This hour is already reserved.') return False i += 1 update.message.reply_text('This hour is not available to reserve.') return False
def check_confirmation(update, context): now = datetime.now() two_hours = now + timedelta(days=2) reservation = sess.query(Reservation).filter( Reservation.day <= two_hours, Reservation.is_expired != True, Reservation.is_confirmed != True).order_by(Reservation.day).first() if reservation: response = "Your reservation No `" + str( reservation.id_) + " " + reservation.day.strftime( '%Y-%m-%d %H:%M') + "`" if update.message.text == '❌ Cancel': sess.delete(reservation) sess.commit() response += ' cancelled' elif update.message.text == '✅ Confirm': reservation.is_confirmed = True sess.commit() response += ' confirmed' update.message.reply_text(response, reply_markup=ReplyKeyboardMarkup( main_menu, resize_keyboard=True, one_time_keyboard=True), parse_mode=ParseMode.MARKDOWN) return True else: unknown(update, context)
def choose_day(update, context): if re.match('\d\d$|\d$', update.message.text) is not None: day = int(update.message.text) if 0 < day <= calendar.monthrange( 2019, userState[update.message.chat.id]['month'])[1]: userState[update.message.chat.id]['day'] = day reply_keyboard = HOURS reserves = sess.query(Reservation).filter_by( day=date(2019, int(userState[update.message.chat.id]['month']), int(userState[update.message.chat.id]['day']))) for res in reserves: i = 0 for slots in HOURS: if res.slot in slots: reply_keyboard[i].pop(reply_keyboard[i].index( res.slot)) i += 1 update.message.reply_text('Choose the hour, you want to reserve.', reply_markup=ReplyKeyboardMarkup( reply_keyboard, resize_keyboard=True, one_time_keyboard=True)) reserved = 'This hours are already reserved.\n' for res in reserves: print(res.slot, res.day) reserved += res.slot + '\n' if reserved == 'This hours are already reserved.\n': reserved = 'Day is free.' update.message.reply_text(reserved) return True return False
def cancel_reservation(update, context): reservations = sess.query(Reservation).filter_by( user_id=update.message.chat.id).order_by(Reservation.day) response = "Choose the number of reservation you want to cancel:\n" i = 1 buttons = [] for res in reservations: if res.day.month < date.today().month: sess.delete(res) continue elif res.day.month == date.today( ).month and res.day.day < date.today().day: sess.delete(res) continue response += str(i) + ". Date:" + str(res.day) + " Time:" + str( res.slot) + "\n" buttons.append(str(i)) i += 1 userState[update.message.chat.id] = {} userState[update.message.chat.id]['reservations'] = i - 1 if response == "Choose the number of reservation you want to cancel:\n": response = "You don't have reservations." update.message.reply_text(response, reply_markup=ReplyKeyboardMarkup( buttons, resize_keyboard=True, one_time_keyboard=True))
def choose_hour(update, context): hours = get_hours() if update.message.text in hours: splitted_time = update.message.text.split(':') chosen_day = datetime(YEAR, int(context.user_data['month']), int(context.user_data['day']), int(splitted_time[0]), int(splitted_time[1]), 0) check = sess.query(Reservation).filter_by( day=chosen_day, slot=update.message.text ).first() if check is None: res = Reservation( user_id=update.message.chat.id, day=chosen_day, slot=update.message.text ) sess.add(res) waitinglist = sess.query(WaitingList).filter( WaitingList.user_id == update.message.chat.id, WaitingList.day == date(chosen_day.year, chosen_day.month, chosen_day.day), ).first() if waitinglist: sess.delete(waitinglist) sess.commit() text = 'Time `' + chosen_day.strftime("%Y-%m-%d %H:%M") + '` reserved successfully' update.message.reply_text(text, reply_markup=ReplyKeyboardMarkup(base.main_menu, resize_keyboard=True), parse_mode=ParseMode.MARKDOWN) return ConversationHandler.END update.message.reply_text('This hour is already reserved') elif update.message.text == 'Back': context.user_data['wrong_day'] = True choose_month(update, context) return DAY elif update.message.text == 'Subscribe to waiting list': response = subscribe_user_to_waiting_list(context, update.message.chat.id) update.message.reply_text(response, parse_mode=ParseMode.MARKDOWN) base.cancel(update, context) return ConversationHandler.END elif update.message.text == 'Cancel': base.cancel(update, context) return ConversationHandler.END else: context.user_data['wrong_hour'] = True update.message.reply_text('Wrong hour') choose_day(update, context) return HOUR
def delete_reservation(update, context): if re.match('\d$', update.message.text) is not None: num = int(update.message.text) if num > userState[update.message.chat.id]['reservations']: return False x = sess.query(Reservation).filter_by( user_id=update.message.chat.id)[num - 1] sess.delete(x) userState[update.message.chat.id] = {} update.message.reply_text('Reservation was canceled.') cancel(update, context) elif update.message.text == "Cancel": cancel(update, context)
def subscribe_user_to_waiting_list(context, user_id): chosen_day = date(YEAR, int(context.user_data['month']), int(context.user_data['day'])) waitinglist = sess.query(WaitingList).filter( WaitingList.user_id == user_id, WaitingList.day == chosen_day, ).first() if waitinglist: return 'You are already in Waiting list for `' + chosen_day.strftime("%Y-%m-%d") + '`' new_waitinglist = WaitingList( user_id=user_id, day=chosen_day, ) sess.add(new_waitinglist) sess.commit() return 'You are added to Waiting list successfully for `' + chosen_day.strftime("%Y-%m-%d") + '`. The bot will notify you if any reservation on this day is cancelled'
def start(update, context): user = User(id_=update.message.chat.id, telegramID=update.message.chat.username) check = sess.query(User).get(update.message.chat.id) if check is None: sess.add(user) sess.commit() update.message.reply_text( 'Welcome to BBQ reserver telegram bot.\n' 'By can book a time slot for barbecue zone in Innopolis city, Republic Tatarstan!\n\n' 'Main features of bot:\n' '- view available time slots for barbecue zone;\n' '- a book time slot for barbecue zone;\n' '- cancel booking;\n' 'Send /cancel if you want to return to the main menu(just in case)', reply_markup=ReplyKeyboardMarkup(main_menu, resize_keyboard=True))
def sendNotification(context: CallbackContext): now = datetime.now() period = now + timedelta(hours=24) #should be hours reservations = sess.query(Reservation).filter( Reservation.day <= period, Reservation.is_expired != True, Reservation.is_confirmed != True ).order_by(Reservation.day).all() if reservations: keyboard = [['✅ Confirm', '❌ Cancel']] for reservation in reservations: response = "Your have a reservation `" + str(reservation.id_) + "` at " + reservation.day.strftime('%H:%M') + " on " + reservation.day.strftime('%Y-%m-%d') + "` for the BBQZone. Confirm your reservation" context.bot.send_message( chat_id=reservation.user_id, text=response, reply_markup=ReplyKeyboardMarkup(keyboard, resize_keyboard=True, one_time_keyboard=True), parse_mode=ParseMode.MARKDOWN )
def view_reservations(update, context): reservations = sess.query(Reservation).filter_by( user_id=update.message.chat.id).order_by(Reservation.day) response = "You have made the following reservations:\n" i = 1 for res in reservations: if res.day.month < date.today().month: sess.delete(res) continue elif res.day.month == date.today( ).month and res.day.day < date.today().day: sess.delete(res) continue response += str(i) + ". Date:" + str(res.day) + " Time:" + str( res.slot) + "\n" i += 1 if response == "You have that reservations:\n": response = "You don't have any reservation." update.message.reply_text(response) cancel(update, context)
def view_reservations(update, context): reservations = sess.query(Reservation).filter( Reservation.user_id == update.message.chat.id, Reservation.is_expired != True, Reservation.day > datetime.now()).all() if reservations: response = "You have made the following reservations:```\n" for res in reservations: response += "ID:" + str(res.id_) + " Time: " + res.day.strftime( "%Y-%m-%d %H:%M") + "\n" response += '```' else: response = "You have not made any reservations yet" update.message.reply_text(response, reply_markup=ReplyKeyboardMarkup( main_menu, resize_keyboard=True, one_time_keyboard=True), parse_mode=ParseMode.MARKDOWN) return True