Did some other modifications
This commit is contained in:
@@ -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()
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user