- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 58
 
Sponsorship email logic #205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Closed
      
      
    
  
     Closed
                    Changes from all commits
      Commits
    
    
            Show all changes
          
          
            45 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      cca40df
              
                Add sponsorship profile and Tier models with admin and forms
              
              
                lidokogi 8ac7ae0
              
                Merge branch 'main' of https://github.com/lidokogi/pyladiescon-portal
              
              
                lidokogi 14781a1
              
                Finalize Sponsorship form and clean up error handling
              
              
                lidokogi cc35880
              
                Remove db.sqlite3 from repo and add it to .gitignore
              
              
                lidokogi b9fbd07
              
                Update .gitignore to ignore __pycache__ and Python bytecode files
              
              
                lidokogi 1003bf2
              
                Update portal/settings.py
              
              
                lidokogi c7b0dca
              
                Remove __pycache__ and .pyc files from repo
              
              
                lidokogi bf317ba
              
                Merge branch 'main' of https://github.com/lidokogi/pyladiescon-portal
              
              
                lidokogi 193324b
              
                Update Homepage to Link to Sponsorship Form
              
              
                lidokogi 94f60d5
              
                Update portal/settings.py
              
              
                lidokogi cb2fe7c
              
                Update portal/settings.py
              
              
                lidokogi eeef289
              
                Update portal/settings.py
              
              
                lidokogi 649691d
              
                Update portal/settings.py
              
              
                lidokogi 957b63a
              
                Delete image files
              
              
                lidokogi 79e5554
              
                Merge branch 'main' of https://github.com/lidokogi/pyladiescon-portal
              
              
                lidokogi 4ca02de
              
                Make main_contact readonly and finalize sponsorship form behavior
              
              
                lidokogi 9feecb3
              
                Temporarily remove additional_contacts field to simplify PR as suggested
              
              
                lidokogi 3891194
              
                Refactor application_status to use Python StrEnum for improved clarity
              
              
                lidokogi 2d16a68
              
                Add Pillow dependency for ImageField support
              
              
                lidokogi 8ee3350
              
                Merge branch 'main' into main
              
              
                lidokogi 91ac57f
              
                Implement Sponsorship App changes
              
              
                lidokogi 62eddea
              
                Add python-dotenv to fix missing module error in CI
              
              
                lidokogi c7ea9f0
              
                Fix: Add python-dotenv to correct requirements file used by CI
              
              
                lidokogi f00df82
              
                Fix import order
              
              
                lidokogi ecdbe07
              
                Add complete tests for sponsorship profile
              
              
                lidokogi fbdf682
              
                Remove media files from repo and ignore media directory
              
              
                lidokogi 1a740bb
              
                Revert ALLOWED_HOSTS to original env-based configuration
              
              
                lidokogi 0c59ff3
              
                Revert default DB name and password to 'postgres' and 'password'
              
              
                lidokogi c0b50fc
              
                Move sponsorship URL include to portal/urls.py as requested
              
              
                lidokogi f6c0df5
              
                Squash sponsorship migrations into one initial migration
              
              
                lidokogi 5325bc3
              
                Revert volunteer to migration 0006 and remove 0007 & 0008
              
              
                lidokogi 7945388
              
                Update templates/portal/index.html
              
              
                lidokogi b0d04c2
              
                Update templates/portal/index.html
              
              
                lidokogi 9eeebef
              
                chore: apply code formatting from make reformat
              
              
                lidokogi c32dfae
              
                Update sponsorship/templates/sponsorship/sponsorship_profile_form.html
              
              
                lidokogi e2eef86
              
                Update sponsorship/templates/sponsorship/sponsorship_profile_form.html
              
              
                lidokogi 9d7d374
              
                Update sponsorship/templates/sponsorship/sponsorship_profile_form.html
              
              
                lidokogi 3b3b0e4
              
                Fix linter errors: quotes, method case, endblock names
              
              
                lidokogi bd388e2
              
                Update sponsorship/templates/sponsorship/create_profile.html
              
              
                lidokogi 931f0dc
              
                Update sponsorship/templates/sponsorship/sponsorship_profile_form.html
              
              
                lidokogi cf3f557
              
                Remove dotenv function from settings
              
              
                lidokogi c79c6ab
              
                fix errors
              
              
                lidokogi d6723e3
              
                Fix test logic with correct image function
              
              
                lidokogi cd8f6e7
              
                Implement sponsorship email notification logic
              
              
                lidokogi 39348d0
              
                Resolved merge conflicts
              
              
                lidokogi File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| 
          
            
          
           | 
    @@ -30,4 +30,5 @@ staticroot/ | |
| 
     | 
||
| site/ | ||
| htmlcov/ | ||
| /media/ | ||
| 
     | 
||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| 
          
            
          
           | 
    @@ -14,3 +14,4 @@ boto3==1.38.5 | |
| django-storages==1.14.6 | ||
| django-widget-tweaks==1.5.0 | ||
| pillow==11.2.1 | ||
| python-dotenv | ||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| 
          
            
          
           | 
    @@ -10,3 +10,4 @@ pytest-django==4.8.0 | |
| pytest==8.3.5 | ||
| pytest-cov==6.1.1 | ||
| coverage==7.7.0 | ||
| python-dotenv | ||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1 +1,14 @@ | ||
| -r requirements-docs.txt | ||
| python-dotenv | ||
| asgiref==3.8.1 | ||
| Django==5.1.7 | ||
| django-allauth==65.5.0 | ||
| gunicorn==23.0.0 | ||
| packaging==24.2 | ||
| psycopg2-binary==2.9.10 | ||
| sqlparse==0.5.3 | ||
| django-bootstrap5==25.1 | ||
| whitenoise==6.9.0 | ||
| dj-database-url==2.3.0 | ||
| Pillow==11.1.0 | ||
| 
     | 
              Empty file.
          
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| from django.contrib import admin | ||
| from .models import SponsorshipProfile, SponsorshipTier | ||
| 
     | 
||
| # Register your models here. | ||
| @admin.register(SponsorshipTier) | ||
| class SponsorshipTierAdmin(admin.ModelAdmin): | ||
| list_display = ('name', 'amount') | ||
| search_fields = ('name',) | ||
| ordering = ('amount',) | ||
| 
     | 
||
| @admin.register(SponsorshipProfile) | ||
| class SponsorshipProfileAdmin(admin.ModelAdmin): | ||
| list_display = ('sponsor_organization_name', 'main_contact','sponsorship_type', 'application_status') | ||
| list_filter = ('sponsorship_type', 'application_status', 'sponsorship_tier') | ||
| search_fields = ('sponsor_organization_name', 'main_contact__username') | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| from django.apps import AppConfig | ||
| 
     | 
||
| class SponsorshipConfig(AppConfig): | ||
| default_auto_field = 'django.db.models.BigAutoField' | ||
| name = 'sponsorship' | ||
| 
     | 
||
| def ready(self): | ||
| import sponsorship.signals # this registers the signals | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| from django.core.mail import send_mail | ||
| from django.template.loader import render_to_string | ||
| from django.conf import settings | ||
| 
     | 
||
| def send_sponsorship_status_emails(profile): | ||
| user = profile.user | ||
| 
     | 
||
| # Email to sponsor | ||
| sponsor_subject = "Your Sponsorship Profile Has Been Approved" | ||
| sponsor_message = render_to_string("sponsorship/email/sponsor_status_update.txt", { | ||
| "user": user, | ||
| "profile": profile | ||
| }) | ||
| send_mail( | ||
| sponsor_subject, | ||
| sponsor_message, | ||
| settings.DEFAULT_FROM_EMAIL, | ||
| [user.email] | ||
| ) | ||
| 
     | 
||
| # Email to internal team (hardcoded for now) | ||
| team_subject = f"New Sponsorship Approved: {profile.organization_name}" | ||
| team_message = render_to_string("sponsorship/email/team_status_notification.txt", { | ||
| "user": user, | ||
| "profile": profile | ||
| }) | ||
| send_mail( | ||
| team_subject, | ||
| team_message, | ||
| settings.DEFAULT_FROM_EMAIL, | ||
| ["[email protected]"] # Replace with actual team emails later | ||
| ) | ||
| def send_sponsorship_profile_email(user, profile, is_update=False): | ||
| subject = "Sponsorship Profile Submission Received" | ||
| message = render_to_string("sponsorship/email/sponsor_status_update.txt", { | ||
| "user": user, | ||
| "profile": profile, | ||
| "is_update": is_update | ||
| }) | ||
| 
     | 
||
| send_mail( | ||
| subject, | ||
| message, | ||
| settings.DEFAULT_FROM_EMAIL, | ||
| [user.email], | ||
| fail_silently=False, | ||
| ) | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| from django import forms | ||
| 
     | 
||
| from .models import SponsorshipProfile | ||
| 
     | 
||
| 
     | 
||
| class SponsorshipProfileForm(forms.ModelForm): | ||
| class Meta: | ||
| model = SponsorshipProfile | ||
| fields = [ | ||
| 'main_contact', | ||
| 'sponsor_organization_name', | ||
| 'sponsorship_type', | ||
| 'sponsorship_tier', | ||
| 'logo', | ||
| 'company_description', | ||
| 'application_status', | ||
| ] | ||
| widgets = { | ||
| 'company_description': forms.Textarea(attrs={'rows': 4,}), | ||
| } | ||
| 
     | 
||
| def __init__(self, *args, **kwargs): | ||
| user = kwargs.pop("user", None) # Expecting current user from the view | ||
| super().__init__(*args, **kwargs) | ||
| 
     | 
||
| if user: | ||
| self.fields["main_contact"].initial = user | ||
| self.fields["main_contact"].disabled = True # Makes it read-only | ||
| 
     | 
||
| def save(self, commit=True): | ||
| instance = super().save(commit=False) | ||
| instance.main_contact = self._user # Enforce value | ||
| instance.application_status = 'pending' # Set status manually | ||
| if commit: | ||
| instance.save() | ||
| self.save_m2m() | ||
| return instance | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # Generated by Django 5.1.7 on 2025-03-29 05:58 | ||
| 
     | 
||
| import django.db.models.deletion | ||
| from django.conf import settings | ||
| from django.db import migrations, models | ||
| 
     | 
||
| 
     | 
||
| class Migration(migrations.Migration): | ||
| 
     | 
||
| initial = True | ||
| 
     | 
||
| dependencies = [ | ||
| migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
| ] | ||
| 
     | 
||
| operations = [ | ||
| migrations.CreateModel( | ||
| name='SponsorshipTier', | ||
| fields=[ | ||
| ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
| ('amount', models.DecimalField(decimal_places=2, max_digits=10)), | ||
| ('name', models.CharField(max_length=100)), | ||
| ('description', models.TextField()), | ||
| ], | ||
| ), | ||
| migrations.CreateModel( | ||
| name='SponsorshipProfile', | ||
| fields=[ | ||
| ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
| ('sponsor_organization_name', models.CharField(max_length=255)), | ||
| ('sponsorship_type', models.CharField(choices=[('individual', 'Individual'), ('organization', 'Organization/Company')], max_length=20)), | ||
| ('logo', models.ImageField(upload_to='sponsor_logos/')), | ||
| ('company_description', models.TextField()), | ||
| ('application_status', models.CharField(choices=[('pending', 'Pending'), ('approved', 'Approved'), ('rejected', 'Rejected'), ('cancelled', 'Cancelled')], default='pending', max_length=20)), | ||
| ('additional_contacts', models.ManyToManyField(blank=True, related_name='additional_sponsorship_contacts', to=settings.AUTH_USER_MODEL)), | ||
| ('main_contact', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='main_contact_for', to=settings.AUTH_USER_MODEL)), | ||
| ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='sponsorship_profile', to=settings.AUTH_USER_MODEL)), | ||
| ('sponsorship_tier', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='sponsorship.sponsorshiptier')), | ||
| ], | ||
| ), | ||
| ] | 
              Empty file.
          
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| from django.db import models | ||
| from django.contrib.auth.models import User | ||
| from enum import StrEnum | ||
| 
     | 
||
| 
     | 
||
| class SponsorshipTier(models.Model): | ||
| amount = models.DecimalField(max_digits=10, decimal_places=2) | ||
| name = models.CharField(max_length=100) | ||
| description = models.TextField() | ||
| 
     | 
||
| def __str__(self): | ||
| return self.name | ||
| 
     | 
||
| class ApplicationStatus(StrEnum): | ||
| PENDING = "pending" | ||
| APPROVED = "approved" | ||
| REJECTED = "rejected" | ||
| CANCELLED = "cancelled" | ||
| 
     | 
||
| class SponsorshipProfile(models.Model): | ||
| INDIVIDUAL = 'individual' | ||
| ORGANIZATION = 'organization' | ||
| 
     | 
||
| SPONSORSHIP_TYPE_CHOICES = [ | ||
| (INDIVIDUAL, 'Individual'), | ||
| (ORGANIZATION, 'Organization/Company'), | ||
| ] | ||
| 
     | 
||
| user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='sponsorship_profile') | ||
| main_contact = models.OneToOneField(User, on_delete=models.CASCADE, related_name='main_contact_for') | ||
| additional_contacts = models.ManyToManyField(User, blank=True, related_name='additional_sponsorship_contacts') | ||
| sponsor_organization_name = models.CharField(max_length=255) | ||
| sponsorship_type = models.CharField(max_length=20, choices=SPONSORSHIP_TYPE_CHOICES) | ||
| sponsorship_tier = models.ForeignKey(SponsorshipTier, on_delete=models.SET_NULL, null=True) | ||
| logo = models.ImageField(upload_to='sponsor_logos/') | ||
| company_description = models.TextField() | ||
| application_status = models.CharField( | ||
| max_length=20, | ||
| choices=[(status.value, status.name.capitalize()) for status in ApplicationStatus], | ||
| default=ApplicationStatus.PENDING.value, | ||
| ) | ||
| 
     | 
||
| 
     | 
||
| def __str__(self): | ||
| return self.sponsor_organization_name | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| from django.db.models.signals import post_save | ||
| from django.dispatch import receiver | ||
| from .models import SponsorshipProfile | ||
| from django.conf import settings | ||
| from django.template.loader import render_to_string | ||
| from django.core.mail import EmailMultiAlternatives | ||
| from django.contrib.sites.models import Site | ||
| 
     | 
||
| 
     | 
||
| def _send_email(subject, recipient_list, *, html_template=None, text_template=None, context=None): | ||
| context = context or {} | ||
| context["current_site"] = Site.objects.get_current() | ||
| 
     | 
||
| text_content = render_to_string(text_template, context) | ||
| html_content = render_to_string(html_template, context) | ||
| 
     | 
||
| msg = EmailMultiAlternatives( | ||
| subject, | ||
| text_content, | ||
| settings.DEFAULT_FROM_EMAIL, | ||
| recipient_list, | ||
| ) | ||
| msg.attach_alternative(html_content, "text/html") | ||
| msg.send() | ||
| 
     | 
||
| 
     | 
||
| @receiver(post_save, sender=SponsorshipProfile) | ||
| def sponsorship_profile_signal(sender, instance, created, **kwargs): | ||
| """Send emails when sponsorship profile is submitted or approved.""" | ||
| if created: | ||
| # Email on submission | ||
| subject = f"{settings.ACCOUNT_EMAIL_SUBJECT_PREFIX} Sponsorship Application Received" | ||
| _send_email( | ||
| subject, | ||
| [instance.user.email], | ||
| html_template="sponsorship/email/sponsor_status_update.html", | ||
| text_template="sponsorship/email/sponsor_status_update.txt", | ||
| context={"profile": instance}, | ||
| ) | ||
| elif instance.application_status == "approved": | ||
| # Email on approval | ||
| subject = f"{settings.ACCOUNT_EMAIL_SUBJECT_PREFIX} Sponsorship Profile Approved" | ||
| _send_email( | ||
| subject, | ||
| [instance.user.email], | ||
| html_template="sponsorship/email/sponsor_approved.html", | ||
| text_template="sponsorship/email/sponsor_approved.txt", | ||
| context={"profile": instance}, | ||
| ) | ||
| 
     | 
||
| # Internal team notification | ||
| internal_subject = f"{settings.ACCOUNT_EMAIL_SUBJECT_PREFIX} New Sponsorship Approved: {instance.organization_name}" | ||
| _send_email( | ||
| internal_subject, | ||
| ["[email protected]"], # Replace with real internal emails later | ||
| html_template="sponsorship/email/team_status_notification.html", | ||
| text_template="sponsorship/email/team_status_notification.txt", | ||
| context={"profile": instance}, | ||
| ) | ||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| {% extends "base.html" %} | ||
| {% block content %} | ||
| <h2> | ||
| Create Sponsorship Profile | ||
| </h2> | ||
| <form method="post" enctype="multipart/form-data"> | ||
| {% csrf_token %} | ||
| {{ form.as_p }} | ||
| <button type="submit"> | ||
| Submit | ||
| </button> | ||
| </form> | ||
| {% endblock content %} | 
        
          
          
            7 changes: 7 additions & 0 deletions
          
          7 
        
  sponsorship/templates/sponsorship/email/sponsor_approved.html
  
  
      
      
   
        
      
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| <p>Hi {{ profile.user.first_name }},</p> | ||
| 
     | 
||
| <p>Congratulations! Your sponsorship application for {{ profile.organization_name }} has been approved 🎉</p> | ||
| 
     | 
||
| <p>We're excited to have you as a sponsor for PyLadiesCon. A team member will reach out soon with next steps and onboarding information.</p> | ||
| 
     | 
||
| <p>Best,<br>The PyLadiesCon Team</p> | 
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is calling the internal _send_email() function. Should it call either the send_sponsorship_profile_email or send_sponsorship_status_emails?