Handle login/logout flows, more navigation, and add notification emails
This commit is contained in:
@@ -132,6 +132,14 @@ SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.environ['SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET'
|
||||
SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS = ['andrew.cmu.edu']
|
||||
SOCIAL_AUTH_GOOGLE_OAUTH2_AUTH_EXTRA_ARGUMENTS = {'hd': 'andrew.cmu.edu' }
|
||||
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/items/'
|
||||
LOGIN_URL = '/login/google-oauth2/'
|
||||
|
||||
# email settings
|
||||
EMAIL_HOST = 'smtp.gmail.com'
|
||||
EMAIL_PORT = '465'
|
||||
EMAIL_USE_SSL = True
|
||||
EMAIL_HOST_USER = 'fincom.bot@gmail.com'
|
||||
EMAIL_HOST_PASSWORD = os.environ['EMAIL_PASSWORD']
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/1.10/topics/i18n/
|
||||
|
||||
@@ -19,6 +19,7 @@ from . import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.index, name='index'),
|
||||
url(r'^logout$', views.user_logout, name='logout'),
|
||||
url(r'^items/', include('items.urls')),
|
||||
url('', include('social_django.urls', namespace='social')),
|
||||
url(r'^admin/', admin.site.urls),
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
from django.http import HttpResponse
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.contrib.auth import logout
|
||||
from django.template import loader
|
||||
|
||||
def index(request):
|
||||
if request.user.is_authenticated():
|
||||
return HttpResponseRedirect('/items')
|
||||
|
||||
template = loader.get_template('fincom/index.html')
|
||||
return HttpResponse(template.render({}, request))
|
||||
|
||||
def user_logout(request):
|
||||
logout(request)
|
||||
|
||||
return HttpResponseRedirect('/')
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.mail import send_mail
|
||||
from storages.backends.s3boto3 import S3Boto3Storage
|
||||
from stdimage.models import StdImageField
|
||||
from datetime import datetime, date
|
||||
@@ -59,6 +60,49 @@ class Item(models.Model):
|
||||
def __str__(self):
|
||||
return self.committee.name + ": " + self.event + " " + self.desc
|
||||
|
||||
def mail_com_chair(self):
|
||||
send_mail(
|
||||
'New Reimbursement - ' + self.event + ': ' + self.desc,
|
||||
'Hey ' + self.committee.chair.first_name + ',\n\n' + \
|
||||
'Please take a moment to review http://fincom.delt.space/items/' + \
|
||||
str(self.pk) + ' and approve or reject the request from ' + \
|
||||
self.created_by.first_name + ' ' + self.created_by.last_name + \
|
||||
'. If you have any questions, contact the treasurer.\n\n' + \
|
||||
'Have a fiscally responsible day,\n Fincom Bot',
|
||||
'fincom.bot@gmail.com',
|
||||
[self.committee.chair.email],
|
||||
html_message='Hey ' + self.committee.chair.first_name+',<br><br>' +\
|
||||
'Please take a moment to review ' + \
|
||||
'<a href="http://fincom.delt.space/items/' + \
|
||||
str(self.pk) + '">http://fincom.delt.space/items/' + str(self.pk) +\
|
||||
'</a> and approve or reject the request from ' + \
|
||||
self.created_by.first_name + ' ' + self.created_by.last_name + \
|
||||
'. If you have any questions, contact the treasurer.<br><br>' + \
|
||||
'Have a fiscally responsible day,<br><br><em>Fincom Bot</em>'
|
||||
)
|
||||
|
||||
def mail_fincom(self):
|
||||
emails = [s.email for s in User.objects.filter(groups__name='Fincom')]
|
||||
|
||||
send_mail(
|
||||
'Preapproved Reimbursement - ' + self.event + ': ' + self.desc,
|
||||
'Hey Fincom,\n\n' + \
|
||||
'Please take a moment to review http://fincom.delt.space/items/' + \
|
||||
str(self.pk) + ' and approve or reject the request from ' + \
|
||||
self.created_by.first_name + ' ' + self.created_by.last_name + \
|
||||
'.\n\nHave a fiscally responsible day,\n Fincom Bot',
|
||||
'fincom.bot@gmail.com',
|
||||
emails,
|
||||
html_message='Hey Fincom,<br><br>' + \
|
||||
'Please take a moment to review ' + \
|
||||
'<a href="http://fincom.delt.space/items/' + \
|
||||
str(self.pk) + '">http://fincom.delt.space/items/' + str(self.pk) +\
|
||||
'</a> and approve or reject the request from ' + \
|
||||
self.created_by.first_name + ' ' + self.created_by.last_name + \
|
||||
'.<br><br>' + \
|
||||
'Have a fiscally responsible day,<br><br> <em>Fincom Bot</em>'
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def parseDate(date_str):
|
||||
try:
|
||||
|
||||
@@ -15,7 +15,7 @@ def authError():
|
||||
|
||||
def myItems(user):
|
||||
if (user.groups.filter(name='Fincom').exists()):
|
||||
return Items.objects.order_by('-date_filed', 'desc')
|
||||
return Item.objects.order_by('-date_filed', 'desc')
|
||||
|
||||
comms = []
|
||||
for c in Committee.objects.all():
|
||||
@@ -42,13 +42,15 @@ def list(request):
|
||||
@login_required
|
||||
def details(request, item_id):
|
||||
I = Item.objects.get(pk=item_id)
|
||||
if (not isAuthorised(request, I)):
|
||||
return HttpResponseRedirect('/items/' + str(item_id) + '/edit')
|
||||
if (not isAuthorised(request, I)
|
||||
and request.user != I.created_by):
|
||||
return authError()
|
||||
|
||||
template = loader.get_template('items/details.html')
|
||||
|
||||
context = {
|
||||
'I': I,
|
||||
'approve': isAuthorised(request, I),
|
||||
}
|
||||
return HttpResponse(template.render(context, request))
|
||||
|
||||
@@ -62,6 +64,7 @@ def approve(request, item_id):
|
||||
if (I.committee.chair == request.user and
|
||||
I.status == Item.NEW):
|
||||
I.status = Item.PREAPPROVED
|
||||
I.mail_fincom()
|
||||
elif (request.user.groups.filter(name='Fincom').exists()):
|
||||
I.status = Item.PROCESSED
|
||||
|
||||
@@ -147,6 +150,8 @@ def new_form(request):
|
||||
|
||||
item.save()
|
||||
|
||||
item.mail_com_chair()
|
||||
|
||||
return HttpResponseRedirect('/items')
|
||||
|
||||
else:
|
||||
|
||||
@@ -26,3 +26,17 @@
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
color: $text;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
margin: $pad-m 0;
|
||||
padding: $pad-l;
|
||||
border-radius: $pad-s;
|
||||
border: 1px solid $midgray;
|
||||
|
||||
span {
|
||||
color: $midgray;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,23 @@ body {
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
float: right;
|
||||
color: $gold;
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.pull-right {
|
||||
float: right;
|
||||
margin: $pad-l;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin-bottom: $pad-xl;
|
||||
|
||||
& > div {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
@@ -50,6 +64,7 @@ body {
|
||||
border: solid 1px $midgray;
|
||||
box-shadow: 0px 3px 9px lighten($shadowgray, 20%);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="nav">
|
||||
<a href="/logout">logout</a>
|
||||
<h3>Fincom Web App</h3>
|
||||
</div>
|
||||
<div class="container">
|
||||
|
||||
@@ -6,13 +6,21 @@
|
||||
{% include "./item.html" %}
|
||||
|
||||
<div class="approve">
|
||||
{% if I.details %}
|
||||
<div class="details">
|
||||
<span>Details:</span><br>
|
||||
{{ I.details }}</div>
|
||||
{% endif %}
|
||||
<div class="status">Status: <span>{{ I.statusText }}</span></div>
|
||||
|
||||
<div class="actions">
|
||||
{% if approve %}
|
||||
<a href="/items/{{ I.pk }}/approve" class="btn">Approve</a>
|
||||
<a href="/items/{{ I.pk }}/reject" class="btn">Reject</a>
|
||||
{% endif %}
|
||||
<a href="/items/{{ I.pk }}/delete" class="btn">Delete</a>
|
||||
<a href="/items/{{ I.pk }}/edit" class="btn">Edit</a>
|
||||
<a href="/items" class="btn">Back</a>
|
||||
</div>
|
||||
|
||||
<a href="{{ I.image.url }}"><img src="{{ I.image.thumbnail.url }}"></a>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
{% block main %}
|
||||
|
||||
<div>
|
||||
<a href="/items" class="btn pull-right">Back</a>
|
||||
<h1>Edit Reimbursements</h1>
|
||||
<hr>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<hr>
|
||||
|
||||
<div class="rcol">
|
||||
Make sure all information is accurate, you submit and itemized receipt, and
|
||||
Make sure all information is accurate, you submit an itemized receipt, and
|
||||
you select the correct committee.
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user