diff --git a/.github/workflows/formatting_backend.yml b/.github/workflows/formatting_backend.yml
index c033780..ff98abf 100644
--- a/.github/workflows/formatting_backend.yml
+++ b/.github/workflows/formatting_backend.yml
@@ -25,7 +25,5 @@ jobs:
- name: Run Formatters
run: |
- flake8 --max-line-length=120 --ignore=E203,E266,E501,W503,F403,F401,E402,F841,C901,F722,F405,F811
- black --check . --line-length=120 --skip-string-normalization
ruff check .
working-directory: backend
diff --git a/backend/.pre-commit-config.yaml b/backend/.pre-commit-config.yaml
index 9dc331b..33343ef 100644
--- a/backend/.pre-commit-config.yaml
+++ b/backend/.pre-commit-config.yaml
@@ -29,20 +29,6 @@ repos:
# Run the formatter.
- id: ruff-format
- - repo: https://github.com/psf/black
- rev: 25.1.0
- hooks:
- - id: black
- language_version: python3.11
- args: [--line-length=120, --skip-string-normalization]
-
- - repo: https://github.com/pycqa/flake8
- rev: 7.1.1
- hooks:
- - id: flake8
- args:
- - --max-line-length=120
- - --ignore=E203,E266,E501,W503,F403,F401,E402,F841,C901,F722,F405,F811
# mypy
# - repo: https://github.com/pre-commit/mirrors-mypy
# rev: 'v1.17.0'
diff --git a/backend/pyproject.toml b/backend/pyproject.toml
index be6df32..6b591c5 100644
--- a/backend/pyproject.toml
+++ b/backend/pyproject.toml
@@ -55,48 +55,43 @@ exclude = [
'^.serverless/',
]
-[tool.black]
-line-length = 120
-skip-string-normalization = true
-target-version = ['py311']
-
[tool.ruff]
line-length = 120
indent-width = 4
target-version = "py311"
exclude = [
- ".bzr",
- ".direnv",
- ".eggs",
- ".git",
- ".git-rewrite",
- ".hg",
- ".ipynb_checkpoints",
- ".mypy_cache",
- ".nox",
- ".pants.d",
- ".pyenv",
- ".pytest_cache",
- ".pytype",
- ".ruff_cache",
- ".svn",
- ".tox",
- ".venv",
- ".vscode",
- "__pypackages__",
- "_build",
- "buck-out",
- "build",
- "dist",
- "node_modules",
- "site-packages",
- "venv",
- ".serverless"
+".bzr",
+".direnv",
+".eggs",
+".git",
+".git-rewrite",
+".hg",
+".ipynb_checkpoints",
+".mypy_cache",
+".nox",
+".pants.d",
+".pyenv",
+".pytest_cache",
+".pytype",
+".ruff_cache",
+".svn",
+".tox",
+".venv",
+".vscode",
+"pypackages",
+"_build",
+"buck-out",
+"build",
+"dist",
+"node_modules",
+"site-packages",
+"venv",
+".serverless"
]
[tool.ruff.lint]
ignore = [
- "E203", "E266", "E501", "F403", "F401", "E402", "F841", "C901", "F722", "F405", "F811"
+"E203", "E266", "E501", "F403", "F401", "E402", "F841", "C901", "F722", "F405", "F811"
]
select = ["E4", "E7", "E9", "F"]
fixable = ["ALL"]
diff --git a/backend/usecase/payment_tracking_usecase.py b/backend/usecase/payment_tracking_usecase.py
index 76fd56d..4883547 100644
--- a/backend/usecase/payment_tracking_usecase.py
+++ b/backend/usecase/payment_tracking_usecase.py
@@ -1,5 +1,6 @@
from datetime import datetime, timezone
from http import HTTPStatus
+from typing import Optional
import ulid
from model.email.email import EmailIn, EmailType
@@ -36,6 +37,7 @@ def process_payment_event(self, message_body: dict) -> None:
registration_data = registration_details.registrationData
event_id = registration_details.eventId
entry_id = registration_details.entryId
+ recorded_registration_data = None
if transaction_status == TransactionStatus.PENDING:
logger.info(f'Skipping PENDING message for entryId: {entry_id}')
@@ -57,15 +59,23 @@ def process_payment_event(self, message_body: dict) -> None:
logger.info(f'Payment transaction status updated to {transaction_status} for entryId {entry_id}')
- recorded_registration_data = self._create_and_save_registration(payment_tracking_body=payment_tracking_body)
+ if transaction_status == TransactionStatus.SUCCESS:
+ recorded_registration_data = self._create_and_save_registration(
+ payment_tracking_body=payment_tracking_body
+ )
+ if not recorded_registration_data:
+ logger.error(f'Failed to save registration for entryId {entry_id}')
self._send_email_notification(
+ first_name=registration_data.firstName,
+ email=registration_data.email,
+ transaction_id=entry_id,
recorded_registration=recorded_registration_data,
ticket_type=registration_data.ticketType.value,
status=transaction_status,
event_detail=event_detail,
)
- logger.info(f'Successfully processed and saved registration for {registration_data.email}')
+ logger.info(f'Successfully processed registration for {registration_data.email}')
except Exception as e:
logger.error(f'Failed to process successful payment for entryId {registration_details.entryId}: {e}')
@@ -138,106 +148,100 @@ def _create_and_save_registration(self, payment_tracking_body: PaymentTrackingBo
def _send_email_notification(
self,
- recorded_registration: Registration,
+ email: str,
+ first_name: str,
+ transaction_id: str,
ticket_type: str,
- status: str,
+ status: TransactionStatus,
event_detail: Event,
is_pycon_event: bool = True,
+ recorded_registration: Optional[Registration] = None,
):
- def _email_list_elements(elements: list[str]):
+ """
+ Sends an email notification based on the transaction status and event type.
+ """
+ if not event_detail:
+ logger.error('Event details are missing. Cannot send email.')
+ return
+
+ def _email_list_elements(elements: list[str]) -> str:
return '\n'.join([f'
{element}' for element in elements])
- def _email_bold_element(element: str):
+ def _email_bold_element(element: str) -> str:
return f'{element}'
- def _email_newline_element():
+ def _email_newline_element() -> str:
return '
'
- pycon_email_templates = {
- TransactionStatus.SUCCESS: {
- 'subject': "You're all set for PyCon Davao 2025!",
- 'salutation': f'Hi {recorded_registration.firstName},',
- 'body': [
- "Thank you for registering for PyCon Davao 2025 by DurianPy! Your payment was successful, and we're excited to see you at the event.",
- _email_bold_element('Below is a summary of your registration details:'),
- _email_list_elements(
- [
- f'Registration ID: {recorded_registration.registrationId}',
- f'Ticket Type: {ticket_type.capitalize()}',
- f'Sprint Day Participation: {"Yes" if recorded_registration.sprintDay else "No"}',
- (
- f'Amount Paid: ₱{recorded_registration.amountPaid:.2f}'
- if recorded_registration.amountPaid is not None
- else 'Amount Paid: ₱0'
- ),
- ]
- ),
- _email_newline_element(),
- 'See you there!',
- ],
- 'regards': ['Best,'],
- },
- TransactionStatus.FAILED: {
- 'subject': 'Issue with your PyCon Davao 2025 Payment',
- 'salutation': f'Hi {recorded_registration.firstName},',
- 'body': [
- 'There was an issue processing your payment for PyCon Davao 2025. Please check your payment details or try again.',
- f'If the problem persists, please contact our support team at durianpy.davao@gmail.com and present your transaction ID: {recorded_registration.transactionId}',
- ],
- 'regards': ['Sincerely,'],
- },
- }
-
- email_templates = {
+ def _create_success_body(reg_data: Registration, ticket: str) -> list[str]:
+ logger.info(f'Creating success email body for registration: {reg_data}')
+ base_body = [
+ f"Thank you for registering for {event_detail.name}! Your payment was successful, and we're excited to see you at the event.",
+ _email_bold_element('Below is a summary of your registration details:'),
+ ]
+
+ list_items = [
+ f'Registration ID: {reg_data.registrationId if reg_data.registrationId else "N/A"}',
+ f'Ticket Type: {ticket.capitalize()}',
+ f'Sprint Day Participation: {"Yes" if reg_data.sprintDay else "No"}',
+ f'Amount Paid: ₱{reg_data.amountPaid:.2f}' if reg_data.amountPaid is not None else 'Amount Paid: ₱0',
+ f'Transaction ID: {reg_data.transactionId if reg_data.transactionId else "N/A"}',
+ ]
+
+ if is_pycon_event:
+ base_body[
+ 0
+ ] = "Thank you for registering for PyCon Davao 2025 by DurianPy! Your payment was successful, and we're excited to see you at the event."
+ list_items.pop()
+
+ base_body.append(_email_list_elements(list_items))
+ base_body.append(_email_newline_element())
+ base_body.append('See you there!')
+
+ return base_body
+
+ def _create_failed_body(name: str, transaction_id: str) -> list[str]:
+ return [
+ f'There was an issue processing your payment for {name}. Please check your payment details or try again.',
+ f'If the problem persists, please contact our support team at durianpy.davao@gmail.com and present your transaction ID: {transaction_id}',
+ ]
+
+ templates = {
TransactionStatus.SUCCESS: {
'subject': f"You're all set for {event_detail.name}!",
- 'salutation': f'Hi {recorded_registration.firstName},',
- 'body': [
- f"Thank you for registering for {event_detail.name}! Your payment was successful, and we're excited to see you at the event.",
- _email_bold_element('Below is a summary of your registration details:'),
- _email_list_elements(
- [
- f'Registration ID: {recorded_registration.registrationId}',
- f'Ticket Type: {ticket_type.capitalize()}',
- f'Sprint Day Participation: {"Yes" if recorded_registration.sprintDay else "No"}',
- (
- f'Amount Paid: ₱{recorded_registration.amountPaid:.2f}'
- if recorded_registration.amountPaid is not None
- else 'Amount Paid: ₱0'
- ),
- f'Transaction ID: {recorded_registration.transactionId}',
- ]
- ),
- _email_newline_element(),
- 'See you there!',
- ],
+ 'salutation': f'Hi {first_name},',
+ 'body': lambda: _create_success_body(recorded_registration, ticket_type),
'regards': ['Best,'],
},
TransactionStatus.FAILED: {
'subject': f'Issue with your {event_detail.name} Payment',
- 'salutation': f'Hi {recorded_registration.firstName},',
- 'body': [
- f'There was an issue processing your payment for {event_detail.name}. Please check your payment details or try again.',
- f'If the problem persists, please contact our support team at durianpy.davao@gmail.com and present your transaction ID: {recorded_registration.transactionId}',
- ],
+ 'salutation': f'Hi {first_name},',
+ 'body': lambda: _create_failed_body(event_detail.name, transaction_id),
'regards': ['Sincerely,'],
},
}
- template_dict = pycon_email_templates if is_pycon_event else email_templates
- template = template_dict.get(status)
-
- if template:
- email_in = EmailIn(
- to=[recorded_registration.email],
- subject=template['subject'],
- salutation=template['salutation'],
- body=template['body'],
- regards=template['regards'],
- emailType=EmailType.REGISTRATION_EMAIL,
- eventId=event_detail.eventId,
- isDurianPy=True,
- )
- self.email_usecase.send_email(email_in=email_in, event=event_detail)
- else:
+ if is_pycon_event:
+ templates[TransactionStatus.SUCCESS]['subject'] = "You're all set for PyCon Davao 2025!"
+ templates[TransactionStatus.FAILED]['subject'] = 'Issue with your PyCon Davao 2025 Payment'
+
+ template = templates.get(status)
+
+ if not template:
logger.error(f'No email template found for status: {status}')
+ return
+
+ logger.info(f'Preparing to send email for event {event_detail.eventId} with status {status} to {email}.')
+
+ email_in = EmailIn(
+ to=[email],
+ subject=template['subject'],
+ salutation=template['salutation'],
+ body=template['body'](),
+ regards=template['regards'],
+ emailType=EmailType.REGISTRATION_EMAIL,
+ eventId=event_detail.eventId,
+ isDurianPy=is_pycon_event,
+ )
+ self.email_usecase.send_email(email_in=email_in, event=event_detail)
+ logger.info(f'Email notification sent for event {event_detail.eventId} with status {status}.')