diff --git a/hr/app_defines.py b/hr/app_defines.py index 8bd0104..5a4288b 100644 --- a/hr/app_defines.py +++ b/hr/app_defines.py @@ -1,3 +1,8 @@ +# Permission Levels +HR_NONE = 0 +HR_VIEWONLY = 1 +HR_ADMIN = 2 + # Application Status Codes APPLICATION_STATUS_NOTSUBMITTED = 0 APPLICATION_STATUS_AWAITINGREVIEW = 1 @@ -27,7 +32,7 @@ AUDIT_EVENT_CHOICES = ( (AUDIT_EVENT_NOTE, 'Staff Note'), (AUDIT_EVENT_REJECTION, 'Rejection Reason'), (AUDIT_EVENT_ACCEPTED, 'Accepted'), - (AUDIT_EVENT_MESSAGE, 'Message to User'), + (AUDIT_EVENT_MESSAGE, 'Message'), ) # Blacklist Type Codes diff --git a/hr/urls.py b/hr/urls.py index a6fb52f..7ece177 100644 --- a/hr/urls.py +++ b/hr/urls.py @@ -5,7 +5,6 @@ from hr import views urlpatterns = patterns('', ('^$', views.index), (r'^recommendation/$', views.view_recommendations), - (r'^recommendation/(?P\d+)/$', views.view_recommendation), (r'^application/$', views.view_applications), (r'^application/(?P\d+)/$', views.view_application), (r'^application/(?P\d+)/update/(?P\d+)/$', views.update_application), diff --git a/hr/views.py b/hr/views.py index ce2158e..272b4d0 100644 --- a/hr/views.py +++ b/hr/views.py @@ -10,12 +10,10 @@ from django.template.loader import render_to_string import settings -from eve_api.models import EVEAccount, EVEPlayerCorporation +from eve_api.models import EVEAccount, EVEPlayerCorporation, EVEPlayerCharacter from reddit.models import RedditAccount - from hr.forms import CreateRecommendationForm, CreateApplicationForm, NoteForm from hr.models import Recommendation, Application, Audit - from app_defines import * ### Shared Functions @@ -35,41 +33,57 @@ def send_message(application, message_type, note=None): ib = Inbox(settings.REDDIT_USER, settings.REDDIT_PASSWD) ib.send(application.user.redditaccount_set.all()[0].username, subject, message) + +def check_permissions(user, application=None): + """ Check if the user has permissions to view or admin the application """ + + hrgroup, created = Group.objects.get_or_create(name=settings.HR_STAFF_GROUP) + if not application: + if hrgroup in user.groups.all() or user.is_superuser: + return HR_ADMIN + else: + if user.is_superuser: + return HR_ADMIN + elif application.user == user: + return HR_VIEWONLY + elif hrgroup in user.groups.all(): + corplist = EVEPlayerCharacter.objects.filter(eveaccount__user=user).values_list('corporation__id', flat=True) + if application.corporation.id in corplist: + return HR_ADMIN + return HR_NONE + ### General Views def index(request): - if request.user.is_staff or Group.objects.get(name=settings.HR_STAFF_GROUP) in request.user.groups.all(): - hrstaff = True - + hrstaff = check_permissions(request.user) return render_to_response('hr/index.html', locals(), context_instance=RequestContext(request)) ### Application Management @login_required def view_applications(request): + """ Shows a list of the user's applications """ + apps = Application.objects.filter(user=request.user) return render_to_response('hr/applications/view_list.html', locals(), context_instance=RequestContext(request)) @login_required def view_application(request, applicationid): + """ View a individual application """ + app = get_object_or_404(Application, id=applicationid) - if not app.user == request.user and not (request.user.is_staff or Group.objects.get(name=settings.HR_STAFF_GROUP) in request.user.groups.all()): - return HttpResponseRedirect(reverse('hr.views.index')) - - if request.user.is_staff or Group.objects.get(name=settings.HR_STAFF_GROUP) in request.user.groups.all(): + hrlvl = check_permissions(request.user, app) + if hrlvl == 1: + audit = app.audit_set.filter(event__in=[AUDIT_EVENT_STATUSCHANGE, AUDIT_EVENT_REJECTION, AUDIT_EVENT_ACCEPTED, AUDIT_EVENT_MESSAGE]) + elif hrlvl == 2: hrstaff = True audit = app.audit_set.all() else: - hrstaff = False - audit = app.audit_set.filter(event__in=[AUDIT_EVENT_STATUSCHANGE, AUDIT_EVENT_REJECTION, AUDIT_EVENT_ACCEPTED]) - - eveacc = app.user.eveaccount_set.all() - redditacc = app.user.redditaccount_set.all() - recs = app.recommendation_set.all() + return HttpResponseRedirect(reverse('hr.views.index')) posts = [] - for acc in redditacc: + for acc in app.user.redditaccount_set.all(): try: accposts = acc.recent_posts() except: @@ -81,6 +95,7 @@ def view_application(request, applicationid): @login_required def add_application(request): + """ Create a new application to a corporation """ clsform = CreateApplicationForm(request.user) if request.method == 'POST': @@ -91,11 +106,7 @@ def add_application(request): request.user.message_set.create(message="This character is already a member of %s" % form.cleaned_data['corporation']) return HttpResponseRedirect(reverse('hr.views.view_applications')) - app = Application() - - app.user = request.user - app.character = form.cleaned_data['character'] - app.corporation = form.cleaned_data['corporation'] + app = Application(user=request.user, character=form.cleaned_data['character'], corporation=form.cleaned_data['corporation']) app.save() request.user.message_set.create(message="Your application to %s has been created." % app.corporation) @@ -113,29 +124,21 @@ def add_application(request): @login_required def view_recommendations(request): - recs = Recommendation.objects.filter(user=request.user, application__status=0) - return render_to_response('hr/recommendations/view_list.html', locals(), context_instance=RequestContext(request)) + """ View a list of recommendations the user has made """ -@login_required -def view_recommendation(request, recommendationid): - rec = get_object_or_404(Recommendation, id=recommendationid, user=request.user) - return render_to_response('hr/recommendations/view.html', locals(), context_instance=RequestContext(request)) + recs = Recommendation.objects.filter(user=request.user) + return render_to_response('hr/recommendations/view_list.html', locals(), context_instance=RequestContext(request)) @login_required def add_recommendation(request): clsform = CreateRecommendationForm(request.user) - if request.method == 'POST': form = clsform(request.POST) if form.is_valid(): - rec = Recommendation() - - rec.user = request.user + rec = Recommendation(user=request.user, created_by=request.user, last_updated_by=request.user) rec.user_character = form.cleaned_data['character'] rec.application = form.cleaned_data['application'] - rec.created_by = request.user - rec.last_updated_by = request.user rec.save() request.user.message_set.create(message="Recommendation added to %s's application" % rec.application ) @@ -148,88 +151,117 @@ def add_recommendation(request): @login_required def admin_applications(request): - if not (request.user.is_staff or Group.objects.get(name=settings.HR_STAFF_GROUP) in request.user.groups.all()): + if check_permissions(request.user) < HR_ADMIN: return HttpResponseRedirect(reverse('hr.views.index')) + # Get the list of viewable applications by the admin + corplist = EVEPlayerCharacter.objects.filter(eveaccount__user=request.user).values_list('corporation', flat=True) + apps = Application.objects.filter(corporation__id__in=corplist) + if 'q' in request.GET: query = request.GET['q'] if 'l' in request.GET: limit = request.get['l'] else: limit = 10 - apps = Application.objects.filter(character__name__icontains=query)[:limit] + apps = apps.filter(character__name__icontains=query)[:limit] else: view_status = [APPLICATION_STATUS_AWAITINGREVIEW, APPLICATION_STATUS_ACCEPTED, APPLICATION_STATUS_QUERY] - apps = Application.objects.filter(status__in=view_status) + apps = apps.filter(status__in=view_status) return render_to_response('hr/applications/admin/view_list.html', locals(), context_instance=RequestContext(request)) @login_required def update_application(request, applicationid, status): + """ Update a application's status """ - hrstaff = (request.user.is_staff or Group.objects.get(name=settings.HR_STAFF_GROUP) in request.user.groups.all()) app = get_object_or_404(Application, id=applicationid) - - # Allow admins and users that are setting the application as awaiting review - if hrstaff or app.user == request.user: + if check_permissions(request.user, app): if not app.status == status: app.status = status app.save(user=request.user) - return HttpResponseRedirect(reverse('hr.views.view_application', args=[applicationid])) @login_required -def add_note(request, applicationid): - if request.method == 'POST': - obj = Audit(application=Application.objects.get(id=applicationid), user=request.user, event=AUDIT_EVENT_NOTE) - form = NoteForm(request.POST, instance=obj) - if form.is_valid(): - form.save() - return HttpResponseRedirect(reverse('hr.views.view_application', args=[applicationid])) +def add_note(request, applicationid): + """ Add a note to a application """ - form = NoteForm() - return render_to_response('hr/applications/add_note.html', locals(), context_instance=RequestContext(request)) + if check_permissions(request.user) == HR_ADMIN: + if request.method == 'POST': + app = Application.objects.get(id=applicationid) + if check_permissions(request.user, app) == HR_ADMIN: + obj = Audit(application=app, user=request.user, event=AUDIT_EVENT_NOTE) + form = NoteForm(request.POST, instance=obj) + if form.is_valid(): + obj = form.save() + return HttpResponseRedirect(reverse('hr.views.view_application', args=[applicationid])) + form = NoteForm() + return render_to_response('hr/applications/add_note.html', locals(), context_instance=RequestContext(request)) + + return render_to_response('hr/index.html', locals(), context_instance=RequestContext(request)) + + +@login_required def add_message(request, applicationid): - if request.method == 'POST': - obj = Audit(application=Application.objects.get(id=applicationid), user=request.user, event=AUDIT_EVENT_MESSAGE) - form = NoteForm(request.POST, instance=obj) - if form.is_valid(): - form.save() - send_message(obj.application, 'message', note=obj.text) - return HttpResponseRedirect(reverse('hr.views.view_application', args=[applicationid])) + """ Send a message to the end user and note it on the application """ + app = get_object_or_404(Application, id=applicationid) - form = NoteForm() - return render_to_response('hr/applications/add_message.html', locals(), context_instance=RequestContext(request)) + if check_permissions(request.user, app): + if request.method == 'POST': + obj = Audit(application=app, user=request.user, event=AUDIT_EVENT_MESSAGE) + form = NoteForm(request.POST, instance=obj) + if form.is_valid(): + obj = form.save() + if not app.user == request.user: + send_message(obj.application, 'message', note=obj.text) + return HttpResponseRedirect(reverse('hr.views.view_application', args=[applicationid])) + form = NoteForm() + return render_to_response('hr/applications/add_message.html', locals(), context_instance=RequestContext(request)) + + return render_to_response('hr/index.html', locals(), context_instance=RequestContext(request)) @login_required -def reject_application(request, applicationid): - if request.method == 'POST': - obj = Audit(application=Application.objects.get(id=applicationid), user=request.user, event=AUDIT_EVENT_REJECTION) - form = NoteForm(request.POST, instance=obj) - if form.is_valid(): - obj = form.save() - obj.application.status = APPLICATION_STATUS_REJECTED - obj.application.save(user=request.user) - send_message(obj.application, 'rejected', note=obj.text) - return HttpResponseRedirect(reverse('hr.views.view_application', args=[applicationid])) +def reject_application(request, applicationid): + """ Reject the application and notify the user """ - form = NoteForm() - return render_to_response('hr/applications/reject.html', locals(), context_instance=RequestContext(request)) + if check_permissions(request.user) == HR_ADMIN: + if request.method == 'POST': + app = Application.objects.get(id=applicationid) + if check_permissions(request.user, app) == HR_ADMIN: + obj = Audit(application=app, user=request.user, event=AUDIT_EVENT_REJECTION) + form = NoteForm(request.POST, instance=obj) + if form.is_valid(): + obj = form.save() + obj.application.status = APPLICATION_STATUS_REJECTED + obj.application.save(user=request.user) + send_message(obj.application, 'rejected', note=obj.text) + return HttpResponseRedirect(reverse('hr.views.view_application', args=[applicationid])) + + form = NoteForm() + return render_to_response('hr/applications/reject.html', locals(), context_instance=RequestContext(request)) + + return render_to_response('hr/index.html', locals(), context_instance=RequestContext(request)) @login_required -def accept_application(request, applicationid): - if request.method == 'POST': - obj = Audit(application=Application.objects.get(id=applicationid), user=request.user, event=AUDIT_EVENT_ACCEPTED) - form = NoteForm(request.POST, instance=obj) - if form.is_valid(): - obj = form.save() - obj.application.status = APPLICATION_STATUS_ACCEPTED - obj.application.save(user=request.user) - send_message(obj.application, 'accepted', note=obj.text) - return HttpResponseRedirect(reverse('hr.views.view_application', args=[applicationid])) +def accept_application(request, applicationid): + """ Accept the application and notify the user """ - form = NoteForm() - return render_to_response('hr/applications/accept.html', locals(), context_instance=RequestContext(request)) + if check_permissions(request.user) == HR_ADMIN: + if request.method == 'POST': + app = Application.objects.get(id=applicationid) + if check_permissions(request.user, app) == HR_ADMIN: + obj = Audit(application=app, user=request.user, event=AUDIT_EVENT_ACCEPTED) + form = NoteForm(request.POST, instance=obj) + if form.is_valid(): + obj = form.save() + obj.application.status = APPLICATION_STATUS_ACCEPTED + obj.application.save(user=request.user) + send_message(obj.application, 'accepted', note=obj.text) + return HttpResponseRedirect(reverse('hr.views.view_application', args=[applicationid])) + form = NoteForm() + return render_to_response('hr/applications/accept.html', locals(), context_instance=RequestContext(request)) + + return render_to_response('hr/index.html', locals(), context_instance=RequestContext(request)) diff --git a/templates/hr/applications/view.html b/templates/hr/applications/view.html index 64982c3..ddb6a1d 100644 --- a/templates/hr/applications/view.html +++ b/templates/hr/applications/view.html @@ -23,9 +23,9 @@ {% else %} Withdraw Application,  {% endif %} +Add Message, {% if hrstaff %} -Add Note,  -Send Message to Applicant, +Add Staff Note,  {% if app.status < 2 or app.status = 4 %} Reject Application,  {% ifequal app.blacklisted 0 %} @@ -45,7 +45,7 @@ {% if audit %}

Event Log

- + {% for a in audit %} {% endfor %} @@ -74,16 +74,17 @@ {% if hrstaff %}

EVE Characters

    -{% for acc in eveacc %} +{% for acc in app.user.eveaccount_set.all %} {% for char in acc.characters.all %}
  • {{ char.name }} - {{ char.corporation }} / {{ char.corporation.alliance }} - {{ char.balance|intcomma }} ISK, {{ char.total_sp|intcomma }} SP - EveGate Profile
  • {% endfor %} {% endfor %}
+{% if app.user.redditaccount_set.all %}

Reddit Accounts

    -{% for acc in redditacc %} +{% for acc in app.user.redditaccount_set.all %}
  • {{ acc.username }}{% if acc.validated %} - Validated{%else %} - NOT VALIDATED{% endif %} - {{ acc.date_created }}
  • {% endfor %}
@@ -102,4 +103,5 @@ {% endfor %} {% endif %} +{% endif %} {% endblock %}
Event TypeChanged ByChanged DateEvent Details
Event TypeUserDateEvent Details
{{ a.get_event_display }}{{ a.user }}{{ a.date }}{{ a.text }}