added delete option and simplified crud operation on teacher

This commit is contained in:
Hosein
2026-01-01 11:11:30 +03:30
parent e844392479
commit f03362c313
5 changed files with 143 additions and 114 deletions
+3 -1
View File
@@ -1,6 +1,7 @@
from telebot import types from telebot import types
from database.models import Students from database.models import Students
from bot.utils.formatters import format_student_info from bot.utils.formatters import format_student_info
from bot.utils.crud_helpers import create_entity_markup
def register(bot): def register(bot):
@@ -11,7 +12,8 @@ def register(bot):
if student: if student:
details = format_student_info(student) details = format_student_info(student)
markup = types.InlineKeyboardMarkup() markup = create_entity_markup("student", student_id)
bot.send_message(call.message.chat.id, details, bot.send_message(call.message.chat.id, details,
reply_markup=markup, parse_mode="HTML") reply_markup=markup, parse_mode="HTML")
else: else:
+97 -107
View File
@@ -2,6 +2,7 @@ from telebot import types, TeleBot
from database.models import Teachers from database.models import Teachers
from bot.utils.formatters import format_teacher_info from bot.utils.formatters import format_teacher_info
from bot.handlers.start import startMarkup from bot.handlers.start import startMarkup
from bot.utils.crud_helpers import create_entity_markup
def register(bot: TeleBot): def register(bot: TeleBot):
@@ -9,6 +10,27 @@ def register(bot: TeleBot):
cancelMarkup.add(types.InlineKeyboardButton( cancelMarkup.add(types.InlineKeyboardButton(
"Cancel", callback_data="cancel")) "Cancel", callback_data="cancel"))
TEACHER_FIELDS = [
('name', "the teacher's name"),
('email', "email"),
('phone_number', "phone (<Optional>)"),
('password', "password"),
('username', "username"),
('birthday', "birthday (YY/MM/DD)"),
('about_me', "about me"),
('job_title', "job title"),
]
EDITABLE_FIELDS = {
'name': 2,
'email': 4,
'phone_number': 5,
'password': 3,
'username': 1,
'birthday': 8,
'about_me': 9,
'job_title': 10
}
# Showing details of a Teacher # Showing details of a Teacher
@bot.callback_query_handler(func=lambda call: call.data.startswith('teacher_')) @bot.callback_query_handler(func=lambda call: call.data.startswith('teacher_'))
def show_teacher_details(call): def show_teacher_details(call):
@@ -17,9 +39,8 @@ def register(bot: TeleBot):
if teacher: if teacher:
details = format_teacher_info(teacher) details = format_teacher_info(teacher)
markup = types.InlineKeyboardMarkup() markup = create_entity_markup("teacher", teacher_id)
markup.add(types.InlineKeyboardButton("Edit Teacher",
callback_data=f"edit_teacher_{teacher_id}", switch_inline_query_current_chat="A default name for the teacher..."))
bot.send_message(call.message.chat.id, details, bot.send_message(call.message.chat.id, details,
reply_markup=markup, parse_mode="HTML") reply_markup=markup, parse_mode="HTML")
else: else:
@@ -31,85 +52,50 @@ def register(bot: TeleBot):
@bot.callback_query_handler(func=lambda call: call.data == 'create_teacher') @bot.callback_query_handler(func=lambda call: call.data == 'create_teacher')
def start_teacher_creation(call): def start_teacher_creation(call):
msg = bot.send_message(call.message.chat.id, msg = bot.send_message(call.message.chat.id,
"Please enter the teacher's name:", reply_markup=cancelMarkup) "Please enter following data: (enter any key to start)",
bot.register_next_step_handler( reply_markup=cancelMarkup)
msg, process_name_step) bot.register_next_step_handler(msg, collect_field, {}, 0)
bot.answer_callback_query(call.id) bot.answer_callback_query(call.id)
def process_name_step(message): def collect_field(message, data, step):
name = message.text # Save previous field
msg = bot.send_message( if step > 0:
message.chat.id, f"Name: {name}\n\nNow enter email:", reply_markup=cancelMarkup) field_name = TEACHER_FIELDS[step - 1][0]
bot.register_next_step_handler(msg, process_email_step, name) data[field_name] = message.text
def process_email_step(message, name): # Done collecting?
email = message.text if step >= len(TEACHER_FIELDS):
msg = bot.send_message( show_confirmation(message, data)
message.chat.id, f"Email: {email}\n\nNow enter phone: (<Optional>)", reply_markup=cancelMarkup) return
bot.register_next_step_handler(msg, process_phone_step, name, email)
def process_phone_step(message, name, email): # Ask next question
phone = message.text field_name, prompt = TEACHER_FIELDS[step]
msg = bot.send_message( msg = bot.send_message(message.chat.id, f"Now enter {prompt}:",
message.chat.id, f"Phone: {phone}\n\nNow enter password: ", reply_markup=cancelMarkup)
bot.register_next_step_handler(
msg, process_password_step, name, email, phone)
def process_password_step(message, name, email, phone):
password = message.text
msg = bot.send_message(
message.chat.id, f"password: {password}\n\nNow enter username:", reply_markup=cancelMarkup)
bot.register_next_step_handler(
msg, process_username_step, name, email, phone, password)
def process_username_step(message, name, email, phone, password):
username = message.text
msg = bot.send_message(
message.chat.id, f"username: {username}\n\nNow enter birthday: (YY/MM/DD)", reply_markup=cancelMarkup)
bot.register_next_step_handler(
msg, process_birthday_step, name, email, phone, password, username)
def process_birthday_step(message, name, email, phone, password, username):
birthday = message.text
msg = bot.send_message(
message.chat.id, f"birthday: {birthday}\n\nNow enter about me: ", reply_markup=cancelMarkup)
bot.register_next_step_handler(
msg, process_aboutme_step, name, email, phone, password, username, birthday)
def process_aboutme_step(message, name, email, phone, password, username, birthday):
about_me = message.text
msg = bot.send_message(
message.chat.id, f"about me: {about_me}\n\nNow enter job title: ", reply_markup=cancelMarkup)
bot.register_next_step_handler(
msg, process_jobtitle_step, name, email, phone, password, username, birthday, about_me)
def process_jobtitle_step(message, name, email, phone, password, username, birthday, about_me):
job_title = message.text
msg = bot.send_message(message.chat.id, "is this correct? (enter any key) (Use Cancel to Stop creating)\n"
f"Name: {name}\n"
f"Email: {email}\n"
f"Phone: {phone}\n"
f"Password: {password}\n"
f"Birthday: {birthday}\n"
f"About Me: {about_me}\n"
f"Job Title: {job_title}",
reply_markup=cancelMarkup) reply_markup=cancelMarkup)
bot.register_next_step_handler(msg, collect_field, data, step + 1)
bot.register_next_step_handler( def show_confirmation(message, data):
msg, confirm_teacher_creation, name, email, phone, password, username, birthday, about_me, job_title) summary = "Is this correct? (enter any key to continue or cancel to exit)\n\n" + "\n".join(
f"{name.replace('_', ' ').title()}: {data[name]}"
for name, _ in TEACHER_FIELDS
)
msg = bot.send_message(message.chat.id, summary,
reply_markup=cancelMarkup)
bot.register_next_step_handler(msg, create_teacher, data)
def confirm_teacher_creation(message, name, email, phone, password, username, birthday, about_me, job_title): def create_teacher(message, data):
if (Teachers.createTeacher(name=name, email=email, phone_number=phone, if Teachers.createTeacher(**data):
password=password, username=username, birthday=birthday, bot.send_message(message.chat.id, "✅ Teacher created!",
about_me=about_me, job_title=job_title)): reply_markup=startMarkup())
bot.send_message(message.chat.id, "✅ Teacher created!")
else: else:
bot.send_message(message.chat.id, "❌ Failed to create teacher.") bot.send_message(
message.chat.id, "❌ Failed to create teacher.", reply_markup=startMarkup())
@bot.callback_query_handler(func=lambda call: call.data == 'cancel') @bot.callback_query_handler(func=lambda call: call.data == 'cancel')
def cancel_action(call): def cancel_action(call):
bot.clear_step_handler(call.message) bot.clear_step_handler(call.message)
bot.send_message(call.message.chat.id, "Action cancelled.") bot.send_message(call.message.chat.id,
"Action cancelled.", reply_markup=startMarkup())
bot.answer_callback_query(call.id) bot.answer_callback_query(call.id)
# Editing a Teacher Flow # Editing a Teacher Flow
@@ -118,64 +104,68 @@ def register(bot: TeleBot):
teacher_id = call.data.split('_')[2] teacher_id = call.data.split('_')[2]
teacher = Teachers.getTeachertById(teacher_id) teacher = Teachers.getTeachertById(teacher_id)
if not teacher:
bot.send_message(call.message.chat.id, "Teacher not found.")
bot.answer_callback_query(call.id)
return
editMarkup = types.ReplyKeyboardMarkup( editMarkup = types.ReplyKeyboardMarkup(
resize_keyboard=True, one_time_keyboard=True) resize_keyboard=True, one_time_keyboard=True)
for field in list(EDITABLE_FIELDS.keys()) + ['Cancel']:
for field in ['name', 'email', 'phone_number', 'password', 'username', 'birthday', 'about_me', 'job_title', 'Cancel']:
editMarkup.add(types.KeyboardButton(field.capitalize())) editMarkup.add(types.KeyboardButton(field.capitalize()))
if teacher:
msg = bot.send_message(call.message.chat.id, msg = bot.send_message(call.message.chat.id,
"Please enter the field you want to edit: ", reply_markup=editMarkup) "Please enter the field you want to edit: ", reply_markup=editMarkup)
bot.register_next_step_handler( bot.register_next_step_handler(
msg, process_field_select_step, teacher) msg, process_field_select, teacher)
else:
bot.send_message(call.message.chat.id, "Teacher not found.")
bot.answer_callback_query(call.id) bot.answer_callback_query(call.id)
def process_field_select_step(message, teacher: tuple): def process_field_select(message, teacher: tuple):
field = message.text.lower() field = message.text.lower()
if field == 'cancel': if field == 'cancel':
bot.send_message(message.chat.id, "Action cancelled.")
return
fields = ['id', 'username', 'name', 'created_at', 'email', 'phone_number', 'last_seen', 'is_verfied',
'birthday', 'about_me', 'job_title']
fields_index = {field: i for i, field in enumerate(fields)}
if field in fields:
previous_value = teacher[fields_index[field]]
markup = types.ReplyKeyboardMarkup(
resize_keyboard=True, one_time_keyboard=True, row_width=1)
markup.add(types.KeyboardButton(
f"{previous_value} (current)"), types.KeyboardButton("Cancel"))
msg = bot.send_message(
message.chat.id, f"Please enter new value for {field}:", reply_markup=markup)
bot.register_next_step_handler(
msg, process_value_edit_step, teacher[fields_index["id"]], field, previous_value)
else:
bot.send_message(
message.chat.id, "Invalid field. Action cancelled.")
def process_value_edit_step(message, teacher_id, field, previous_value):
new_value = message.text
if (new_value.lower() == 'cancel'):
bot.send_message(message.chat.id, "Action cancelled.", bot.send_message(message.chat.id, "Action cancelled.",
reply_markup=startMarkup()) reply_markup=startMarkup())
return return
if (new_value == f"{previous_value} (current)"): if field not in EDITABLE_FIELDS:
bot.send_message( bot.send_message(
message.chat.id, f"No changes made to Teacher's {field}.", reply_markup=startMarkup()) message.chat.id, "Invalid field. Action cancelled.")
return return
if (Teachers.updateTeacher(teacher_id, **{field: new_value})): current_value = teacher[EDITABLE_FIELDS[field]]
msg = bot.send_message(
message.chat.id, f"Current value is: {current_value}.\n Please enter new value for {field}:", reply_markup=cancelMarkup)
bot.register_next_step_handler(
msg, process_value_edit, teacher[0], field, current_value)
def process_value_edit(message, teacher_id, field, previous_value):
new_value = message.text
# Handle cancellation
if new_value.lower() == 'cancel' or new_value == f"{previous_value} (current)":
msg = "Action cancelled." if new_value.lower(
) == 'cancel' else f"No changes made to {field}."
bot.send_message(message.chat.id, msg, reply_markup=startMarkup())
return
# Update teacher
if Teachers.updateTeacher(teacher_id, **{field: new_value}):
bot.send_message( bot.send_message(
message.chat.id, f"✅ Teacher's {field} updated successfully.", reply_markup=startMarkup()) message.chat.id, f"✅ Teacher's {field} updated successfully.", reply_markup=startMarkup())
else: else:
bot.send_message( bot.send_message(
message.chat.id, f"❌ Failed to update Teacher's {field}.", reply_markup=startMarkup()) message.chat.id, f"❌ Failed to update Teacher's {field}.", reply_markup=startMarkup())
# Deleting a Teacher
@bot.callback_query_handler(func=lambda call: call.data.startswith('delete_teacher_'))
def delete_teacher(call):
teacher_id = call.data.split('_')[2]
if (Teachers.deleteTeacher(teacher_id)):
bot.send_message(call.message.chat.id, "✅ Teacher deleted.",
reply_markup=startMarkup())
else:
bot.send_message(call.message.chat.id, "❌ Failed to delete Teacher.",
reply_markup=startMarkup())
bot.answer_callback_query(call.id)
+5
View File
@@ -17,6 +17,11 @@ def register(bot):
btn = types.InlineKeyboardButton( btn = types.InlineKeyboardButton(
f"@{row[1]} | id#{row[0]}", callback_data=f"student_{row[0]}") f"@{row[1]} | id#{row[0]}", callback_data=f"student_{row[0]}")
markup.add(btn) markup.add(btn)
# add button for creating a new student
markup.add(types.InlineKeyboardButton(
" Create New Student", callback_data="create_student"))
bot.send_message( bot.send_message(
message.chat.id, "Here is the data:", reply_markup=markup) message.chat.id, "Here is the data:", reply_markup=markup)
else: else:
+11
View File
@@ -0,0 +1,11 @@
from telebot import types
def create_entity_markup(entity_name, enitity_id):
markup = types.InlineKeyboardMarkup()
markup.add(types.InlineKeyboardButton(
f"✏️ Edit {entity_name}", callback_data=f"edit_{entity_name}_{enitity_id}"))
markup.add(types.InlineKeyboardButton(
f"🗑️ Delete {entity_name}", callback_data=f"delete_{entity_name}_{enitity_id}"))
return markup
+21
View File
@@ -154,3 +154,24 @@ class Teachers:
finally: finally:
if conn: if conn:
connection.release_db_connection(conn) connection.release_db_connection(conn)
def deleteTeacher(teacher_id):
conn = None
try:
conn = connection.get_db_connection()
if not conn:
return False
cursor = conn.cursor()
cursor.execute(
"DELETE FROM teachers WHERE id = %s", (teacher_id,))
conn.commit()
cursor.close()
return True
except Exception as e:
logger.error(f"Database query error in deleteTeacher: {e}")
return False
finally:
if conn:
connection.release_db_connection(conn)