redo email for shop and edd email for team app
This commit is contained in:
parent
9d70782b70
commit
49d4f74472
|
@ -1,52 +1,8 @@
|
||||||
from django.core.mail import EmailMultiAlternatives
|
from utils.email import _send_email
|
||||||
from django.conf import settings
|
|
||||||
from django.template.loader import render_to_string
|
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger("bornhack.%s" % __name__)
|
logger = logging.getLogger("bornhack.%s" % __name__)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def send_email(emailtype, recipient, formatdict, subject, sender='BornHack <info@bornhack.dk>', attachment=None):
|
|
||||||
### determine email type, set template and attachment vars
|
|
||||||
html_template=None
|
|
||||||
|
|
||||||
if emailtype == 'invoice':
|
|
||||||
text_template = 'emails/invoice_email.txt'
|
|
||||||
html_template = 'emails/invoice_email.html'
|
|
||||||
attachment_filename = formatdict['filename']
|
|
||||||
elif emailtype == 'creditnote':
|
|
||||||
text_template = 'emails/creditnote_email.txt'
|
|
||||||
html_template = 'emails/creditnote_email.html'
|
|
||||||
attachment_filename = formatdict['creditnote'].filename
|
|
||||||
elif emailtype == 'testmail':
|
|
||||||
text_template = 'emails/testmail.txt'
|
|
||||||
else:
|
|
||||||
logger.error('Unknown email type: %s' % emailtype)
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
### put the basic email together
|
|
||||||
msg = EmailMultiAlternatives(subject, render_to_string(text_template, formatdict), sender, [recipient], [settings.ARCHIVE_EMAIL])
|
|
||||||
|
|
||||||
### is there a html version of this email?
|
|
||||||
if html_template:
|
|
||||||
msg.attach_alternative(render_to_string(html_template, formatdict), 'text/html')
|
|
||||||
|
|
||||||
### is there a pdf attachment to this mail?
|
|
||||||
if attachment:
|
|
||||||
msg.attach(attachment_filename, attachment, 'application/pdf')
|
|
||||||
|
|
||||||
except Exception as E:
|
|
||||||
logger.exception('exception while rendering email: %s' % E)
|
|
||||||
return False
|
|
||||||
|
|
||||||
### send the email
|
|
||||||
msg.send()
|
|
||||||
|
|
||||||
### all good
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def send_creditnote_email(creditnote):
|
def send_creditnote_email(creditnote):
|
||||||
# put formatdict together
|
# put formatdict together
|
||||||
formatdict = {
|
formatdict = {
|
||||||
|
@ -56,15 +12,17 @@ def send_creditnote_email(creditnote):
|
||||||
subject = 'BornHack creditnote %s' % creditnote.pk
|
subject = 'BornHack creditnote %s' % creditnote.pk
|
||||||
|
|
||||||
# send mail
|
# send mail
|
||||||
return send_email(
|
return _send_email(
|
||||||
emailtype='creditnote',
|
text_template='emails/creditnote_email.txt',
|
||||||
|
html_template='emails/creditnote_email.html',
|
||||||
recipient=creditnote.user.email,
|
recipient=creditnote.user.email,
|
||||||
formatdict=formatdict,
|
formatdict=formatdict,
|
||||||
subject=subject,
|
subject=subject,
|
||||||
sender='info@bornhack.dk',
|
|
||||||
attachment=creditnote.pdf.read(),
|
attachment=creditnote.pdf.read(),
|
||||||
|
attachment_filename=creditnote.filename
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def send_invoice_email(invoice):
|
def send_invoice_email(invoice):
|
||||||
# put formatdict together
|
# put formatdict together
|
||||||
formatdict = {
|
formatdict = {
|
||||||
|
@ -76,20 +34,20 @@ def send_invoice_email(invoice):
|
||||||
subject = 'BornHack invoice %s' % invoice.pk
|
subject = 'BornHack invoice %s' % invoice.pk
|
||||||
|
|
||||||
# send mail
|
# send mail
|
||||||
return send_email(
|
return _send_email(
|
||||||
emailtype='invoice',
|
text_template='emails/invoice_email.txt',
|
||||||
|
html_template='emails/invoice_email.html',
|
||||||
recipient=invoice.order.user.email,
|
recipient=invoice.order.user.email,
|
||||||
formatdict=formatdict,
|
formatdict=formatdict,
|
||||||
subject=subject,
|
subject=subject,
|
||||||
sender='info@bornhack.dk',
|
|
||||||
attachment=invoice.pdf.read(),
|
attachment=invoice.pdf.read(),
|
||||||
|
attachment_filename=invoice.filename
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def send_test_email(recipient):
|
def send_test_email(recipient):
|
||||||
return send_email(
|
return _send_email(
|
||||||
emailtype='testmail',
|
text_template='emails/testmail.txt',
|
||||||
recipient=recipient,
|
recipient=recipient,
|
||||||
subject='testmail from bornhack website',
|
subject='testmail from bornhack website'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from .models import Team, TeamArea, TeamMember
|
from .models import Team, TeamArea, TeamMember
|
||||||
|
from .email import send_add_membership_email, send_remove_membership_email
|
||||||
|
|
||||||
admin.site.register(TeamArea)
|
admin.site.register(TeamArea)
|
||||||
|
|
||||||
|
@ -35,11 +35,18 @@ class TeamMemberAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
def add_member(self, request, queryset):
|
def add_member(self, request, queryset):
|
||||||
teams_count = queryset.values('team').distinct().count()
|
teams_count = queryset.values('team').distinct().count()
|
||||||
rows_updated = queryset.update(approved=True)
|
updated = 0
|
||||||
|
|
||||||
|
for membership in queryset:
|
||||||
|
membership.approved = True
|
||||||
|
membership.save()
|
||||||
|
updated += 1
|
||||||
|
send_add_membership_email(membership)
|
||||||
|
|
||||||
self.message_user(
|
self.message_user(
|
||||||
request,
|
request,
|
||||||
'Added {} user(s) to {} team(s).'.format(
|
'Added {} user(s) to {} team(s).'.format(
|
||||||
rows_updated,
|
updated,
|
||||||
teams_count
|
teams_count
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -47,11 +54,17 @@ class TeamMemberAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
def remove_member(self, request, queryset):
|
def remove_member(self, request, queryset):
|
||||||
teams_count = queryset.values('team').distinct().count()
|
teams_count = queryset.values('team').distinct().count()
|
||||||
users_removed = queryset.delete()[0]
|
updated = 0
|
||||||
|
|
||||||
|
for membership in queryset:
|
||||||
|
send_remove_membership_email(membership)
|
||||||
|
membership.delete()
|
||||||
|
updated += 1
|
||||||
|
|
||||||
self.message_user(
|
self.message_user(
|
||||||
request,
|
request,
|
||||||
'Removed {} user(s) from {} team(s).'.format(
|
'Removed {} user(s) from {} team(s).'.format(
|
||||||
users_removed,
|
updated,
|
||||||
teams_count
|
teams_count
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
58
src/teams/email.py
Normal file
58
src/teams/email.py
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
from utils.email import _send_email
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger("bornhack.%s" % __name__)
|
||||||
|
|
||||||
|
|
||||||
|
def send_add_membership_email(membership):
|
||||||
|
formatdict = {
|
||||||
|
'team': membership.team.name,
|
||||||
|
'camp': membership.team.camp.title
|
||||||
|
}
|
||||||
|
|
||||||
|
return _send_email(
|
||||||
|
text_template='emails/add_membership_email.txt',
|
||||||
|
html_template='emails/add_membership_email.html',
|
||||||
|
recipient=membership.user.email,
|
||||||
|
formatdict=formatdict,
|
||||||
|
subject='Team update from {}'.format(membership.team.camp.title)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def send_remove_membership_email(membership):
|
||||||
|
formatdict = {
|
||||||
|
'team': membership.team.name,
|
||||||
|
'camp': membership.team.camp.title
|
||||||
|
}
|
||||||
|
|
||||||
|
if membership.approved:
|
||||||
|
text_template = 'emails/remove_membership_email.txt',
|
||||||
|
html_template = 'emails/remove_membership_email.html'
|
||||||
|
else:
|
||||||
|
text_template = 'emails/unapproved_membership_email.txt',
|
||||||
|
html_template = 'emails/unapproved_membership_email.html'
|
||||||
|
|
||||||
|
return _send_email(
|
||||||
|
text_template=text_template,
|
||||||
|
html_template=html_template,
|
||||||
|
recipient=membership.user.email,
|
||||||
|
formatdict=formatdict,
|
||||||
|
subject='Team update from {}'.format(membership.team.camp.title)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def send_new_membership_email(membership):
|
||||||
|
formatdict = {
|
||||||
|
'team': membership.team.name,
|
||||||
|
'camp': membership.team.camp.title
|
||||||
|
}
|
||||||
|
|
||||||
|
return _send_email(
|
||||||
|
text_template='emails/new_membership_email.txt',
|
||||||
|
html_template='emails/new_membership_email.html',
|
||||||
|
recipient=membership.user.email,
|
||||||
|
formatdict=formatdict,
|
||||||
|
subject='New membership request for {} at {}'.format(
|
||||||
|
membership.team.name,
|
||||||
|
membership.team.camp.title
|
||||||
|
)
|
||||||
|
)
|
|
@ -1,6 +1,9 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models.signals import post_save
|
||||||
|
from django.dispatch import receiver
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
from utils.models import CampRelatedModel
|
from utils.models import CampRelatedModel
|
||||||
|
from .email import send_new_membership_email
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
@ -13,7 +16,10 @@ class TeamArea(CampRelatedModel):
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
description = models.TextField(default='')
|
description = models.TextField(default='')
|
||||||
camp = models.ForeignKey('camps.Camp')
|
camp = models.ForeignKey('camps.Camp')
|
||||||
responsible = models.ManyToManyField('auth.User', related_name='responsible_team_areas')
|
responsible = models.ManyToManyField(
|
||||||
|
'auth.User',
|
||||||
|
related_name='responsible_team_areas'
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{} ({})'.format(self.name, self.camp)
|
return '{} ({})'.format(self.name, self.camp)
|
||||||
|
@ -27,10 +33,18 @@ class Team(CampRelatedModel):
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
slug = models.SlugField(max_length=255, blank=True)
|
slug = models.SlugField(max_length=255, blank=True)
|
||||||
camp = models.ForeignKey('camps.Camp')
|
camp = models.ForeignKey('camps.Camp')
|
||||||
area = models.ForeignKey('teams.TeamArea', related_name='teams', on_delete=models.PROTECT)
|
area = models.ForeignKey(
|
||||||
|
'teams.TeamArea',
|
||||||
|
related_name='teams',
|
||||||
|
on_delete=models.PROTECT
|
||||||
|
)
|
||||||
description = models.TextField()
|
description = models.TextField()
|
||||||
needs_members = models.BooleanField(default=True)
|
needs_members = models.BooleanField(default=True)
|
||||||
members = models.ManyToManyField('auth.User', related_name='teams', through='teams.TeamMember')
|
members = models.ManyToManyField(
|
||||||
|
'auth.User',
|
||||||
|
related_name='teams',
|
||||||
|
through='teams.TeamMember'
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{} ({})'.format(self.name, self.camp)
|
return '{} ({})'.format(self.name, self.camp)
|
||||||
|
@ -61,7 +75,10 @@ class Team(CampRelatedModel):
|
||||||
@property
|
@property
|
||||||
def responsible(self):
|
def responsible(self):
|
||||||
if TeamMember.objects.filter(team=self, responsible=True).exists():
|
if TeamMember.objects.filter(team=self, responsible=True).exists():
|
||||||
return User.objects.filter(teammember__team=self, teammember__responsible=True)
|
return User.objects.filter(
|
||||||
|
teammember__team=self,
|
||||||
|
teammember__responsible=True
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return self.area.responsible.all()
|
return self.area.responsible.all()
|
||||||
|
|
||||||
|
@ -73,5 +90,12 @@ class TeamMember(models.Model):
|
||||||
responsible = models.BooleanField(default=False)
|
responsible = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{} is {} member of team {}'.format(self.user, '' if self.approved else 'an unapproved', self.team)
|
return '{} is {} member of team {}'.format(
|
||||||
|
self.user, '' if self.approved else 'an unapproved', self.team
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=TeamMember)
|
||||||
|
def send_responsible_email(sender, instance, created, **kwargs):
|
||||||
|
if created:
|
||||||
|
send_new_membership_email(instance)
|
||||||
|
|
10
src/teams/templates/emails/add_membership_email.html
Normal file
10
src/teams/templates/emails/add_membership_email.html
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Hello!<br>
|
||||||
|
<br>
|
||||||
|
You're now a member of the {{ team }} team at {{ camp }}.
|
||||||
|
<br>
|
||||||
|
Thank you for helping out!
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Best regards,<br>
|
||||||
|
<br>
|
||||||
|
The BornHack Team<br>
|
10
src/teams/templates/emails/add_membership_email.txt
Normal file
10
src/teams/templates/emails/add_membership_email.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Hello!
|
||||||
|
|
||||||
|
You're now a member of the {{ team }} team at {{ camp }}.
|
||||||
|
|
||||||
|
Thank you for helping out!
|
||||||
|
|
||||||
|
|
||||||
|
Best regards,
|
||||||
|
|
||||||
|
The BornHack Team
|
8
src/teams/templates/emails/new_membership_email.html
Normal file
8
src/teams/templates/emails/new_membership_email.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Hello!<br>
|
||||||
|
<br>
|
||||||
|
There's a new membership request for the {{ team }} team at {{ camp }}.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Best regards,<br>
|
||||||
|
<br>
|
||||||
|
The BornHack Team<br>
|
8
src/teams/templates/emails/new_membership_email.txt
Normal file
8
src/teams/templates/emails/new_membership_email.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Hello!
|
||||||
|
|
||||||
|
There's a new membership request for the {{ team }} team at {{ camp }}.
|
||||||
|
|
||||||
|
|
||||||
|
Best regards,
|
||||||
|
|
||||||
|
The BornHack Team
|
8
src/teams/templates/emails/remove_membership_email.html
Normal file
8
src/teams/templates/emails/remove_membership_email.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Hello!<br>
|
||||||
|
<br>
|
||||||
|
You've been removed from the {{ team }} team at {{ camp }}.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Best regards,<br>
|
||||||
|
<br>
|
||||||
|
The BornHack Team<br>
|
8
src/teams/templates/emails/remove_membership_email.txt
Normal file
8
src/teams/templates/emails/remove_membership_email.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Hello!
|
||||||
|
|
||||||
|
You've been removed from the {{ team }} team at {{ camp }}.
|
||||||
|
|
||||||
|
|
||||||
|
Best regards,
|
||||||
|
|
||||||
|
The BornHack Team
|
|
@ -0,0 +1,8 @@
|
||||||
|
Hello!<br>
|
||||||
|
<br>
|
||||||
|
Your membership of {{ team }} team at {{ camp }} was not approved.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Best regards,<br>
|
||||||
|
<br>
|
||||||
|
The BornHack Team<br>
|
|
@ -0,0 +1,8 @@
|
||||||
|
Hello!
|
||||||
|
|
||||||
|
Your membership of {{ team }} team at {{ camp }} was not approved.
|
||||||
|
|
||||||
|
|
||||||
|
Best regards,
|
||||||
|
|
||||||
|
The BornHack Team
|
46
src/utils/email.py
Normal file
46
src/utils/email.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
from django.core.mail import EmailMultiAlternatives
|
||||||
|
from django.conf import settings
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger("bornhack.%s" % __name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _send_email(
|
||||||
|
text_template,
|
||||||
|
recipient,
|
||||||
|
formatdict,
|
||||||
|
subject,
|
||||||
|
html_template=None,
|
||||||
|
sender='BornHack <info@bornhack.dk>',
|
||||||
|
attachment=None,
|
||||||
|
attachment_filename=None
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
# put the basic email together
|
||||||
|
msg = EmailMultiAlternatives(
|
||||||
|
subject,
|
||||||
|
render_to_string(text_template, formatdict),
|
||||||
|
sender,
|
||||||
|
[recipient],
|
||||||
|
[settings.ARCHIVE_EMAIL]
|
||||||
|
)
|
||||||
|
|
||||||
|
# is there a html version of this email?
|
||||||
|
if html_template:
|
||||||
|
msg.attach_alternative(
|
||||||
|
render_to_string(html_template, formatdict),
|
||||||
|
'text/html'
|
||||||
|
)
|
||||||
|
|
||||||
|
# is there a pdf attachment to this mail?
|
||||||
|
if attachment:
|
||||||
|
msg.attach(attachment_filename, attachment, 'application/pdf')
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception('exception while rendering email: {}'.format(e))
|
||||||
|
return False
|
||||||
|
|
||||||
|
# send the email
|
||||||
|
msg.send()
|
||||||
|
|
||||||
|
return True
|
Loading…
Reference in a new issue