Did some things...
This commit is contained in:
@@ -12,22 +12,23 @@ def format_raffle_details(raffle_id):
|
||||
"""Fetches and formats raffle details for display, including multi-channel prices."""
|
||||
raffle = get_raffle(raffle_id) # Fetches basic info from 'raffles' table
|
||||
if not raffle:
|
||||
return "Error: No se encontró la rifa."
|
||||
return "Error: No se encontró el sorteo."
|
||||
|
||||
details = (
|
||||
f"ℹ️ **Detalles de la rifa** ℹ️\n\n"
|
||||
f"**ID:** `{raffle['id']}`\n"
|
||||
f"**Nombre:** {raffle['name']}\n"
|
||||
f"**Descripción:**\n{raffle['description']}\n\n"
|
||||
f"**Activo:** {'Sí' if raffle['active'] else 'No (Terminado)'}\n"
|
||||
f"**Precio por número (canal principal):** {raffle['price']}€\n"
|
||||
f"ℹ️ <b>Detalles del sorteo</b> ℹ️\n\n"
|
||||
f"<b>ID:</b> <code>{raffle['id']}</code>\n"
|
||||
f"<b>Nombre:</b> {raffle['name']}\n"
|
||||
f"<b>Descripción:</b>\n{raffle['description'][:100]}...\n\n"
|
||||
f"<b>Envío internacional:</b> {'Sí' if raffle['international_shipping'] else 'No'}\n"
|
||||
f"<b>Activo:</b> {'Sí' if raffle['active'] else 'No (Terminado)'}\n"
|
||||
f"<b>Donación mínima (canal principal):</b> {raffle['price']}€\n"
|
||||
)
|
||||
|
||||
# Image ID (optional display)
|
||||
if raffle['image_file_id']:
|
||||
details += f"**ID Imagen:** (Presente)\n"
|
||||
details += f"<b>ID Imagen:</b> {raffle['image_file_id']} (Presente)\n"
|
||||
else:
|
||||
details += f"**ID Imagen:** (No asignada)\n"
|
||||
details += f"<b>ID Imagen:</b> (No asignada)\n"
|
||||
|
||||
# Add participant count and remaining numbers
|
||||
participants = get_participants(raffle_id) # Fetches list of Rows
|
||||
@@ -38,11 +39,25 @@ def format_raffle_details(raffle_id):
|
||||
# pending_participants_count = sum(1 for p in participants if p['step'] == 'waiting_for_payment')
|
||||
|
||||
|
||||
details += f"\n**Participantes Confirmados:** {completed_participants_count}\n"
|
||||
# details += f"**Reservas Pendientes:** {pending_participants_count}\n"
|
||||
details += f"\n<b>Participantes Confirmados:</b> {completed_participants_count}\n"
|
||||
# details += f"<b>Reservas Pendientes:</b> {pending_participants_count}\n"
|
||||
|
||||
remaining_count = get_remaining_numbers_amount(raffle_id)
|
||||
details += f"**Números Disponibles:** {remaining_count if remaining_count >= 0 else 'Error al calcular'}\n"
|
||||
details += f"<b>Números Disponibles:</b> {remaining_count if remaining_count >= 0 else 'Error al calcular'}\n"
|
||||
|
||||
# Gross and net amounts
|
||||
total_gross = 0.0
|
||||
total_fees = 0.0
|
||||
total_net = 0.0
|
||||
invoice_ids = get_all_invoice_ids(raffle_id)
|
||||
for inv_id in invoice_ids:
|
||||
gross, net, fees = get_paypal_amounts_for_invoice(inv_id)
|
||||
total_gross += gross
|
||||
total_fees += fees
|
||||
total_net += net
|
||||
details += f"\n<b>Total Recaudado (bruto):</b> {total_gross:.2f}€\n"
|
||||
details += f"<b>Total Gastos (comisiones):</b> {total_fees:.2f}€\n"
|
||||
details += f"<b>Total Beneficio (neto):</b> {total_net:.2f}€\n"
|
||||
|
||||
return details
|
||||
|
||||
@@ -131,12 +146,12 @@ def get_winners(raffle_id, winner_numbers_int):
|
||||
# if not raffle_details:
|
||||
# logger.error(f"Cannot generate image: Raffle {raffle_id} not found.")
|
||||
# # Draw error message on image
|
||||
# draw.text((10, 10), f"Error: Rifa {raffle_id} no encontrado", fill="red", font=title_font)
|
||||
# draw.text((10, 10), f"Error: Sorteo {raffle_id} no encontrado", fill="red", font=title_font)
|
||||
# img.save(f"/app/data/raffles/raffle_table_{raffle_id}_error.png")
|
||||
# return False # Indicate failure
|
||||
|
||||
# raffle_name = raffle_details['name']
|
||||
# title_text = f"Rifa: {raffle_name}"
|
||||
# title_text = f"Sorteo: {raffle_name}"
|
||||
# # Calculate text bounding box for centering
|
||||
# try:
|
||||
# # Use textbbox for more accurate centering
|
||||
@@ -262,12 +277,12 @@ def generate_table_image(raffle_id):
|
||||
# --- Title Bar ---
|
||||
raffle_details = get_raffle(raffle_id)
|
||||
if not raffle_details:
|
||||
draw.text((10, 10), f"Error: Rifa {raffle_id} no encontrada", fill="red", font=title_font)
|
||||
draw.text((10, 10), f"Error: Sorteo {raffle_id} no encontrado", fill="red", font=title_font)
|
||||
img.save(f"/app/data/raffles/raffle_table_{raffle_id}_error.png")
|
||||
return False
|
||||
|
||||
raffle_name = raffle_details['name']
|
||||
title_text = f"Rifa: {raffle_name}"
|
||||
title_text = f"Sorteo: {raffle_name}"
|
||||
|
||||
# Draw title bar (full width)
|
||||
title_bar_color = "#4a90e2"
|
||||
@@ -403,7 +418,7 @@ def get_paypal_access_token():
|
||||
logger.info(f"Using cached PayPal access token")
|
||||
return old_token
|
||||
logger.info("Fetching new PayPal access token")
|
||||
url = "https://api-m.sandbox.paypal.com/v1/oauth2/token"
|
||||
url = f"{PAYPAL_URL}/v1/oauth2/token"
|
||||
headers = {"Accept": "application/json", "Accept-Language": "en_US"}
|
||||
data = {"grant_type": "client_credentials"}
|
||||
|
||||
@@ -413,8 +428,8 @@ def get_paypal_access_token():
|
||||
store_paypal_access_token(response.json()["access_token"], response.json()["expires_in"])
|
||||
return response.json()["access_token"]
|
||||
|
||||
def create_paypal_order(access_token, value):
|
||||
url = "https://api-m.sandbox.paypal.com/v2/checkout/orders"
|
||||
def create_paypal_order(access_token, value, raffle_id, numbers):
|
||||
url = f"{PAYPAL_URL}/v2/checkout/orders"
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {access_token}"
|
||||
@@ -423,10 +438,12 @@ def create_paypal_order(access_token, value):
|
||||
"intent": "CAPTURE",
|
||||
"purchase_units": [
|
||||
{
|
||||
"amount": {"currency_code": "EUR", "value": f"{value:.2f}"}
|
||||
"amount": {"currency_code": "EUR", "value": f"{value:.2f}"},
|
||||
"description": f"Donación para participar en el sorteo de HomeLabs Club (ID: {raffle_id}, Números: {numbers})",
|
||||
}
|
||||
],
|
||||
"application_context": {
|
||||
"locale": "es-ES",
|
||||
"return_url": f"https://t.me/{BOT_NAME}",
|
||||
"cancel_url": f"https://t.me/{BOT_NAME}"
|
||||
}
|
||||
@@ -439,3 +456,45 @@ def create_paypal_order(access_token, value):
|
||||
# Extract the approval link
|
||||
approval_url = next(link["href"] for link in order["links"] if link["rel"] == "approve")
|
||||
return approval_url, order["id"]
|
||||
|
||||
|
||||
def get_paypal_amounts_for_invoice(invoice_id):
|
||||
"""Fetches the gross, net, and fee amounts for a given PayPal invoice ID."""
|
||||
access_token = get_paypal_access_token()
|
||||
url = f"{PAYPAL_URL}/v2/checkout/orders/{invoice_id}"
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {access_token}"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
except requests.RequestException as e:
|
||||
logger.error(f"Error fetching PayPal invoice {invoice_id}: {e}")
|
||||
return 0.0, 0.0, 0.0
|
||||
|
||||
order = response.json()
|
||||
|
||||
if order["status"] != "COMPLETED":
|
||||
logger.warning(f"Invoice {invoice_id} is not completed. Status: {order['status']}")
|
||||
return 0.0, 0.0, 0.0
|
||||
|
||||
gross_amount = float(order["purchase_units"][0]["amount"]["value"])
|
||||
fee_amount = 0.0
|
||||
net_amount = gross_amount
|
||||
|
||||
# Fetch capture details to get fee information
|
||||
capture_id = order["purchase_units"][0]["payments"]["captures"][0]["id"]
|
||||
capture_url = f"{PAYPAL_URL}/v2/payments/captures/{capture_id}"
|
||||
|
||||
capture_response = requests.get(capture_url, headers=headers)
|
||||
capture_response.raise_for_status()
|
||||
capture_details = capture_response.json()
|
||||
|
||||
if "seller_receivable_breakdown" in capture_details:
|
||||
breakdown = capture_details["seller_receivable_breakdown"]
|
||||
fee_amount = float(breakdown.get("paypal_fee", {}).get("value", 0.0))
|
||||
net_amount = float(breakdown.get("net_amount", {}).get("value", gross_amount))
|
||||
|
||||
return gross_amount, net_amount, fee_amount
|
||||
Reference in New Issue
Block a user