Example #1
0
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
Example #2
0
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
Example #3
0
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)
Example #4
0
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
Example #5
0
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))
Example #6
0
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
Example #7
0
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)
Example #8
0
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'
Example #9
0
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))
Example #10
0
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
            )
Example #11
0
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)
Example #12
0
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