diff --git a/fincom/fincom/settings.py b/fincom/fincom/settings.py index 9d68e2b..a69fd76 100644 --- a/fincom/fincom/settings.py +++ b/fincom/fincom/settings.py @@ -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/ diff --git a/fincom/fincom/urls.py b/fincom/fincom/urls.py index b6f47b4..dca8259 100644 --- a/fincom/fincom/urls.py +++ b/fincom/fincom/urls.py @@ -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), diff --git a/fincom/fincom/views.py b/fincom/fincom/views.py index 8e567b5..c521245 100644 --- a/fincom/fincom/views.py +++ b/fincom/fincom/views.py @@ -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('/') diff --git a/fincom/items/models.py b/fincom/items/models.py index c3359b0..dd549de 100644 --- a/fincom/items/models.py +++ b/fincom/items/models.py @@ -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+',

' +\ + '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.

' + \ + 'Have a fiscally responsible day,

Fincom Bot' + ) + + 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,

' + \ + '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 + \ + '.

' + \ + 'Have a fiscally responsible day,

Fincom Bot' + ) + @staticmethod def parseDate(date_str): try: diff --git a/fincom/items/views.py b/fincom/items/views.py index 0167e31..82dce67 100644 --- a/fincom/items/views.py +++ b/fincom/items/views.py @@ -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: diff --git a/fincom/static/sass/details.scss b/fincom/static/sass/details.scss index 50a1c55..f6bf596 100644 --- a/fincom/static/sass/details.scss +++ b/fincom/static/sass/details.scss @@ -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; + } +} diff --git a/fincom/static/sass/globals.scss b/fincom/static/sass/globals.scss index 67878e5..00c7893 100644 --- a/fincom/static/sass/globals.scss +++ b/fincom/static/sass/globals.scss @@ -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 { diff --git a/fincom/templates/boilerplate.html b/fincom/templates/boilerplate.html index 6b4de0d..a300af2 100644 --- a/fincom/templates/boilerplate.html +++ b/fincom/templates/boilerplate.html @@ -7,6 +7,7 @@
diff --git a/fincom/templates/items/details.html b/fincom/templates/items/details.html index ffc6957..60dae23 100644 --- a/fincom/templates/items/details.html +++ b/fincom/templates/items/details.html @@ -6,13 +6,21 @@ {% include "./item.html" %}
+ {% if I.details %} +
+ Details:
+ {{ I.details }}
+ {% endif %}
Status: {{ I.statusText }}
+ {% if approve %} Approve Reject + {% endif %} Delete Edit + Back
diff --git a/fincom/templates/items/edit.html b/fincom/templates/items/edit.html index f4a988b..128040c 100644 --- a/fincom/templates/items/edit.html +++ b/fincom/templates/items/edit.html @@ -5,6 +5,7 @@ {% block main %}
+Back

Edit Reimbursements


diff --git a/fincom/templates/items/new.html b/fincom/templates/items/new.html index 66cee67..c215ae3 100644 --- a/fincom/templates/items/new.html +++ b/fincom/templates/items/new.html @@ -9,7 +9,7 @@
- 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.