Did some other modifications
This commit is contained in:
@@ -643,3 +643,20 @@ def get_all_invoice_ids(raffle_id):
|
|||||||
return []
|
return []
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
def delete_reservation_timestamp(invoice_id):
|
||||||
|
"""Clears the reservation_timestamp for a participant by invoice_id."""
|
||||||
|
conn = connect_db()
|
||||||
|
cur = conn.cursor()
|
||||||
|
try:
|
||||||
|
cur.execute(
|
||||||
|
"UPDATE participants SET reservation_timestamp=NULL WHERE invoice_id=? AND step='waiting_for_payment'",
|
||||||
|
(invoice_id,)
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
logger.info(f"Cleared reservation_timestamp for invoice {invoice_id}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error clearing reservation_timestamp for invoice {invoice_id}: {e}")
|
||||||
|
conn.rollback()
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
@@ -34,7 +34,7 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||||||
madrid_tz = pytz.timezone("Europe/Madrid")
|
madrid_tz = pytz.timezone("Europe/Madrid")
|
||||||
current_time = datetime.now(madrid_tz)
|
current_time = datetime.now(madrid_tz)
|
||||||
if current_time.time() >= dtime(20, 55) and current_time.time() <= dtime(22, 0):
|
if current_time.time() >= dtime(20, 55) and current_time.time() <= dtime(22, 0):
|
||||||
await update.message.reply_text("No puedes unirte al sorteo en este momento.")
|
await update.message.reply_text("Lo siento, no puedes unirte a sorteos entre las 20:55 y las 22:00 (hora de España) para evitar conflictos con el sorteo en directo. Inténtalo de nuevo más tarde.")
|
||||||
return
|
return
|
||||||
if len(get_reserved_numbers(user.id, raffle_id)) > 0:
|
if len(get_reserved_numbers(user.id, raffle_id)) > 0:
|
||||||
await update.message.reply_text("Ya tienes participaciones reservadas para este sorteo. Por favor, completa la donación o espera a que caduquen antes de unirte de nuevo.")
|
await update.message.reply_text("Ya tienes participaciones reservadas para este sorteo. Por favor, completa la donación o espera a que caduquen antes de unirte de nuevo.")
|
||||||
@@ -433,6 +433,7 @@ async def number_callback(update: Update, context: CallbackContext):
|
|||||||
participant_user_id = participant_data['user_id']
|
participant_user_id = participant_data['user_id']
|
||||||
participant_step = participant_data['step']
|
participant_step = participant_data['step']
|
||||||
participant_db_id = participant_data['id'] # The ID from the participants table
|
participant_db_id = participant_data['id'] # The ID from the participants table
|
||||||
|
user_name = participant_data['user_name'] or participant_data['user_id']
|
||||||
|
|
||||||
if participant_user_id == user_id:
|
if participant_user_id == user_id:
|
||||||
# User clicked a number they already interact with
|
# User clicked a number they already interact with
|
||||||
@@ -440,7 +441,7 @@ async def number_callback(update: Update, context: CallbackContext):
|
|||||||
# User clicked a number they have reserved -> Deselect it
|
# User clicked a number they have reserved -> Deselect it
|
||||||
remove_reserved_number(participant_db_id, number_string)
|
remove_reserved_number(participant_db_id, number_string)
|
||||||
await query.answer(f"Has quitado la reserva de la participación {number_string}.")
|
await query.answer(f"Has quitado la reserva de la participación {number_string}.")
|
||||||
logger.info(f"User {user_id} deselected reserved number {number_string} for raffle {raffle_id}")
|
logger.info(f"User {user_id} (Name: {user_name}) deselected reserved number {number_string} for raffle {raffle_id}")
|
||||||
# Refresh keyboard
|
# Refresh keyboard
|
||||||
keyboard = generate_numbers_keyboard(raffle_id, user_id, page=page)
|
keyboard = generate_numbers_keyboard(raffle_id, user_id, page=page)
|
||||||
await query.edit_message_reply_markup(reply_markup=keyboard)
|
await query.edit_message_reply_markup(reply_markup=keyboard)
|
||||||
@@ -463,7 +464,7 @@ async def number_callback(update: Update, context: CallbackContext):
|
|||||||
# Number is free -> Reserve it for the user
|
# Number is free -> Reserve it for the user
|
||||||
reserve_number(user_id, username, raffle_id, number_string)
|
reserve_number(user_id, username, raffle_id, number_string)
|
||||||
await query.answer(f"Participación {number_string} reservada para ti. Confirma tu selección cuando termines.")
|
await query.answer(f"Participación {number_string} reservada para ti. Confirma tu selección cuando termines.")
|
||||||
logger.info(f"User {user_id} reserved number {number_string} for raffle {raffle_id}")
|
logger.info(f"User {user_id} (Name: {username}) reserved number {number_string} for raffle {raffle_id}")
|
||||||
# Refresh keyboard to show the lock icon
|
# Refresh keyboard to show the lock icon
|
||||||
keyboard = generate_numbers_keyboard(raffle_id, user_id, page=page)
|
keyboard = generate_numbers_keyboard(raffle_id, user_id, page=page)
|
||||||
await query.edit_message_reply_markup(reply_markup=keyboard)
|
await query.edit_message_reply_markup(reply_markup=keyboard)
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ def generate_table_image(raffle_id):
|
|||||||
legend_items = [
|
legend_items = [
|
||||||
("Libre", free_bg_color),
|
("Libre", free_bg_color),
|
||||||
("Reservado", reserved_bg_color),
|
("Reservado", reserved_bg_color),
|
||||||
("Pagado", taken_bg_color)
|
("Asignado", taken_bg_color)
|
||||||
]
|
]
|
||||||
|
|
||||||
spacing = 280 # more spacing between legend items
|
spacing = 280 # more spacing between legend items
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ from database import (
|
|||||||
get_remaining_numbers_amount,
|
get_remaining_numbers_amount,
|
||||||
get_main_message_id,
|
get_main_message_id,
|
||||||
store_update_message_id, get_update_message_id,
|
store_update_message_id, get_update_message_id,
|
||||||
get_last_n_other_participants, get_remaining_numbers
|
get_last_n_other_participants, get_remaining_numbers,
|
||||||
|
delete_reservation_timestamp, cancel_reservation_by_id
|
||||||
)
|
)
|
||||||
from config import BOT_TOKEN, BOT_NAME, WEBHOOK_ID, TYC_DOCUMENT_URL, REVERSE_CHANNELS, NEWRELIC_API_KEY, PAYPAL_URL
|
from config import BOT_TOKEN, BOT_NAME, WEBHOOK_ID, TYC_DOCUMENT_URL, REVERSE_CHANNELS, NEWRELIC_API_KEY, PAYPAL_URL, ADMIN_IDS
|
||||||
from newrelic_telemetry_sdk import Log, LogClient
|
from newrelic_telemetry_sdk import Log, LogClient
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@@ -411,7 +412,12 @@ def paypal_webhook():
|
|||||||
# Capture payment
|
# Capture payment
|
||||||
resource = event["resource"]
|
resource = event["resource"]
|
||||||
invoice_id = resource.get("id") # capture ID
|
invoice_id = resource.get("id") # capture ID
|
||||||
capture_order(invoice_id, access_token)
|
delete_reservation_timestamp(invoice_id)
|
||||||
|
response = capture_order(invoice_id, access_token)
|
||||||
|
if response.get("status") == "COMPLETED":
|
||||||
|
logger.info(f"Payment for order {invoice_id} captured successfully.")
|
||||||
|
else:
|
||||||
|
logger.error(f"Failed to capture payment for order {invoice_id}. Response: {response}")
|
||||||
elif event_type == "PAYMENT.CAPTURE.COMPLETED":
|
elif event_type == "PAYMENT.CAPTURE.COMPLETED":
|
||||||
logger.info(f"✅ Payment completed: {event['resource']['id']}")
|
logger.info(f"✅ Payment completed: {event['resource']['id']}")
|
||||||
resource = event["resource"]
|
resource = event["resource"]
|
||||||
@@ -426,6 +432,55 @@ def paypal_webhook():
|
|||||||
|
|
||||||
# Process the valid payment
|
# Process the valid payment
|
||||||
receive_paypal_payment(invoice_id, payment_status, payment_amount)
|
receive_paypal_payment(invoice_id, payment_status, payment_amount)
|
||||||
|
elif event_type == "PAYMENT.CAPTURE.PENDING":
|
||||||
|
logger.info(f"⏳ Payment pending: {event['resource']['id']}. Awaiting completion.")
|
||||||
|
# Optionally notify user about pending status
|
||||||
|
resource = event["resource"]
|
||||||
|
invoice_id = resource["supplementary_data"]["related_ids"]["order_id"]
|
||||||
|
payment_status = resource.get("status")
|
||||||
|
payment_amount = resource["amount"]["value"]
|
||||||
|
status_details = resource["status_details"]["reason"]
|
||||||
|
|
||||||
|
delete_reservation_timestamp(invoice_id)
|
||||||
|
|
||||||
|
if status_details == "PENDING_REVIEW":
|
||||||
|
logger.info(f"Payment for invoice {invoice_id} is pending review. Notifying admins.")
|
||||||
|
for admin_id in ADMIN_IDS:
|
||||||
|
send_telegram_message(
|
||||||
|
admin_id,
|
||||||
|
f"⚠️ El pago para la factura {invoice_id} está pendiente. "
|
||||||
|
f"Estado actual: '{payment_status}'. "
|
||||||
|
f"Detalles: '{status_details}'. "
|
||||||
|
f"Por favor, revisa manualmente si es necesario."
|
||||||
|
)
|
||||||
|
elif status_details == "REFUNDED":
|
||||||
|
logger.info(f"Payment for invoice {invoice_id} has been refunded. Notifying admins.")
|
||||||
|
for admin_id in ADMIN_IDS:
|
||||||
|
send_telegram_message(
|
||||||
|
admin_id,
|
||||||
|
f"⚠️ El pago para la factura {invoice_id} ha sido reembolsado. "
|
||||||
|
f"Estado actual: '{payment_status}'. "
|
||||||
|
f"Detalles: '{status_details}'. "
|
||||||
|
f"Por favor, revisa manualmente si es necesario."
|
||||||
|
)
|
||||||
|
elif event_type == "PAYMENT.CAPTURE.DENIED":
|
||||||
|
logger.info(f"❌ Payment denied: {event['resource']['id']}. Notifying user.")
|
||||||
|
resource = event["resource"]
|
||||||
|
invoice_id = resource["supplementary_data"]["related_ids"]["order_id"]
|
||||||
|
payment_status = resource.get("status")
|
||||||
|
payment_amount = resource["amount"]["value"]
|
||||||
|
|
||||||
|
participant_data = get_user_by_invoice_id(invoice_id)
|
||||||
|
if participant_data:
|
||||||
|
user_id = participant_data['user_id']
|
||||||
|
cancel_reservation_by_id(participant_data['id'])
|
||||||
|
send_telegram_message(
|
||||||
|
user_id,
|
||||||
|
f"❌ Tu pago para la factura {invoice_id} ha sido denegado. "
|
||||||
|
f"Por favor, inténtalo de nuevo o contacta con un administrador si crees que es un error."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logger.warning(f"Could not find participant data for denied payment invoice {invoice_id}.")
|
||||||
else:
|
else:
|
||||||
logger.info(f"ℹ️ Received event: {event_type}")
|
logger.info(f"ℹ️ Received event: {event_type}")
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user