Did some other modifications

This commit is contained in:
Joan
2025-09-16 23:00:28 +02:00
parent 2bfdb539be
commit 65b8542791
4 changed files with 80 additions and 7 deletions

View File

@@ -641,5 +641,22 @@ def get_all_invoice_ids(raffle_id):
except Exception as e:
logger.error(f"Error getting invoice IDs for raffle {raffle_id}: {e}")
return []
finally:
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()

View File

@@ -34,7 +34,7 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
madrid_tz = pytz.timezone("Europe/Madrid")
current_time = datetime.now(madrid_tz)
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
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.")
@@ -433,6 +433,7 @@ async def number_callback(update: Update, context: CallbackContext):
participant_user_id = participant_data['user_id']
participant_step = participant_data['step']
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:
# 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
remove_reserved_number(participant_db_id, 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
keyboard = generate_numbers_keyboard(raffle_id, user_id, page=page)
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
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.")
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
keyboard = generate_numbers_keyboard(raffle_id, user_id, page=page)
await query.edit_message_reply_markup(reply_markup=keyboard)

View File

@@ -348,7 +348,7 @@ def generate_table_image(raffle_id):
legend_items = [
("Libre", free_bg_color),
("Reservado", reserved_bg_color),
("Pagado", taken_bg_color)
("Asignado", taken_bg_color)
]
spacing = 280 # more spacing between legend items

View File

@@ -16,9 +16,10 @@ from database import (
get_remaining_numbers_amount,
get_main_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
app = Flask(__name__)
@@ -411,7 +412,12 @@ def paypal_webhook():
# Capture payment
resource = event["resource"]
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":
logger.info(f"✅ Payment completed: {event['resource']['id']}")
resource = event["resource"]
@@ -426,6 +432,55 @@ def paypal_webhook():
# Process the valid payment
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:
logger.info(f" Received event: {event_type}")
else: