Reworked HR to work in a multi-corporation enviroment

Allows for multiple corporations to view HR applications in their own limited env.
This commit is contained in:
2010-10-12 22:07:03 +01:00
parent 2ad9b8a09c
commit 701bc5762e
4 changed files with 129 additions and 91 deletions

View File

@@ -1,3 +1,8 @@
# Permission Levels
HR_NONE = 0
HR_VIEWONLY = 1
HR_ADMIN = 2
# Application Status Codes # Application Status Codes
APPLICATION_STATUS_NOTSUBMITTED = 0 APPLICATION_STATUS_NOTSUBMITTED = 0
APPLICATION_STATUS_AWAITINGREVIEW = 1 APPLICATION_STATUS_AWAITINGREVIEW = 1
@@ -27,7 +32,7 @@ AUDIT_EVENT_CHOICES = (
(AUDIT_EVENT_NOTE, 'Staff Note'), (AUDIT_EVENT_NOTE, 'Staff Note'),
(AUDIT_EVENT_REJECTION, 'Rejection Reason'), (AUDIT_EVENT_REJECTION, 'Rejection Reason'),
(AUDIT_EVENT_ACCEPTED, 'Accepted'), (AUDIT_EVENT_ACCEPTED, 'Accepted'),
(AUDIT_EVENT_MESSAGE, 'Message to User'), (AUDIT_EVENT_MESSAGE, 'Message'),
) )
# Blacklist Type Codes # Blacklist Type Codes

View File

@@ -5,7 +5,6 @@ from hr import views
urlpatterns = patterns('', urlpatterns = patterns('',
('^$', views.index), ('^$', views.index),
(r'^recommendation/$', views.view_recommendations), (r'^recommendation/$', views.view_recommendations),
(r'^recommendation/(?P<recommendationid>\d+)/$', views.view_recommendation),
(r'^application/$', views.view_applications), (r'^application/$', views.view_applications),
(r'^application/(?P<applicationid>\d+)/$', views.view_application), (r'^application/(?P<applicationid>\d+)/$', views.view_application),
(r'^application/(?P<applicationid>\d+)/update/(?P<status>\d+)/$', views.update_application), (r'^application/(?P<applicationid>\d+)/update/(?P<status>\d+)/$', views.update_application),

View File

@@ -10,12 +10,10 @@ from django.template.loader import render_to_string
import settings import settings
from eve_api.models import EVEAccount, EVEPlayerCorporation from eve_api.models import EVEAccount, EVEPlayerCorporation, EVEPlayerCharacter
from reddit.models import RedditAccount from reddit.models import RedditAccount
from hr.forms import CreateRecommendationForm, CreateApplicationForm, NoteForm from hr.forms import CreateRecommendationForm, CreateApplicationForm, NoteForm
from hr.models import Recommendation, Application, Audit from hr.models import Recommendation, Application, Audit
from app_defines import * from app_defines import *
### Shared Functions ### Shared Functions
@@ -35,41 +33,57 @@ def send_message(application, message_type, note=None):
ib = Inbox(settings.REDDIT_USER, settings.REDDIT_PASSWD) ib = Inbox(settings.REDDIT_USER, settings.REDDIT_PASSWD)
ib.send(application.user.redditaccount_set.all()[0].username, subject, message) 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 ### General Views
def index(request): def index(request):
if request.user.is_staff or Group.objects.get(name=settings.HR_STAFF_GROUP) in request.user.groups.all(): hrstaff = check_permissions(request.user)
hrstaff = True
return render_to_response('hr/index.html', locals(), context_instance=RequestContext(request)) return render_to_response('hr/index.html', locals(), context_instance=RequestContext(request))
### Application Management ### Application Management
@login_required @login_required
def view_applications(request): def view_applications(request):
""" Shows a list of the user's applications """
apps = Application.objects.filter(user=request.user) apps = Application.objects.filter(user=request.user)
return render_to_response('hr/applications/view_list.html', locals(), context_instance=RequestContext(request)) return render_to_response('hr/applications/view_list.html', locals(), context_instance=RequestContext(request))
@login_required @login_required
def view_application(request, applicationid): def view_application(request, applicationid):
""" View a individual application """
app = get_object_or_404(Application, id=applicationid) 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()): hrlvl = check_permissions(request.user, app)
return HttpResponseRedirect(reverse('hr.views.index')) if hrlvl == 1:
audit = app.audit_set.filter(event__in=[AUDIT_EVENT_STATUSCHANGE, AUDIT_EVENT_REJECTION, AUDIT_EVENT_ACCEPTED, AUDIT_EVENT_MESSAGE])
if request.user.is_staff or Group.objects.get(name=settings.HR_STAFF_GROUP) in request.user.groups.all(): elif hrlvl == 2:
hrstaff = True hrstaff = True
audit = app.audit_set.all() audit = app.audit_set.all()
else: else:
hrstaff = False return HttpResponseRedirect(reverse('hr.views.index'))
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()
posts = [] posts = []
for acc in redditacc: for acc in app.user.redditaccount_set.all():
try: try:
accposts = acc.recent_posts() accposts = acc.recent_posts()
except: except:
@@ -81,6 +95,7 @@ def view_application(request, applicationid):
@login_required @login_required
def add_application(request): def add_application(request):
""" Create a new application to a corporation """
clsform = CreateApplicationForm(request.user) clsform = CreateApplicationForm(request.user)
if request.method == 'POST': 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']) 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')) return HttpResponseRedirect(reverse('hr.views.view_applications'))
app = Application() app = Application(user=request.user, character=form.cleaned_data['character'], corporation=form.cleaned_data['corporation'])
app.user = request.user
app.character = form.cleaned_data['character']
app.corporation = form.cleaned_data['corporation']
app.save() app.save()
request.user.message_set.create(message="Your application to %s has been created." % app.corporation) 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 @login_required
def view_recommendations(request): def view_recommendations(request):
recs = Recommendation.objects.filter(user=request.user, application__status=0) """ View a list of recommendations the user has made """
return render_to_response('hr/recommendations/view_list.html', locals(), context_instance=RequestContext(request))
@login_required recs = Recommendation.objects.filter(user=request.user)
def view_recommendation(request, recommendationid): return render_to_response('hr/recommendations/view_list.html', locals(), context_instance=RequestContext(request))
rec = get_object_or_404(Recommendation, id=recommendationid, user=request.user)
return render_to_response('hr/recommendations/view.html', locals(), context_instance=RequestContext(request))
@login_required @login_required
def add_recommendation(request): def add_recommendation(request):
clsform = CreateRecommendationForm(request.user) clsform = CreateRecommendationForm(request.user)
if request.method == 'POST': if request.method == 'POST':
form = clsform(request.POST) form = clsform(request.POST)
if form.is_valid(): if form.is_valid():
rec = Recommendation() rec = Recommendation(user=request.user, created_by=request.user, last_updated_by=request.user)
rec.user = request.user
rec.user_character = form.cleaned_data['character'] rec.user_character = form.cleaned_data['character']
rec.application = form.cleaned_data['application'] rec.application = form.cleaned_data['application']
rec.created_by = request.user
rec.last_updated_by = request.user
rec.save() rec.save()
request.user.message_set.create(message="Recommendation added to %s's application" % rec.application ) request.user.message_set.create(message="Recommendation added to %s's application" % rec.application )
@@ -148,88 +151,117 @@ def add_recommendation(request):
@login_required @login_required
def admin_applications(request): 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')) 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: if 'q' in request.GET:
query = request.GET['q'] query = request.GET['q']
if 'l' in request.GET: if 'l' in request.GET:
limit = request.get['l'] limit = request.get['l']
else: else:
limit = 10 limit = 10
apps = Application.objects.filter(character__name__icontains=query)[:limit] apps = apps.filter(character__name__icontains=query)[:limit]
else: else:
view_status = [APPLICATION_STATUS_AWAITINGREVIEW, APPLICATION_STATUS_ACCEPTED, APPLICATION_STATUS_QUERY] 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)) return render_to_response('hr/applications/admin/view_list.html', locals(), context_instance=RequestContext(request))
@login_required @login_required
def update_application(request, applicationid, status): 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) app = get_object_or_404(Application, id=applicationid)
if check_permissions(request.user, app):
# Allow admins and users that are setting the application as awaiting review
if hrstaff or app.user == request.user:
if not app.status == status: if not app.status == status:
app.status = status app.status = status
app.save(user=request.user) app.save(user=request.user)
return HttpResponseRedirect(reverse('hr.views.view_application', args=[applicationid])) return HttpResponseRedirect(reverse('hr.views.view_application', args=[applicationid]))
@login_required @login_required
def add_note(request, applicationid): def add_note(request, applicationid):
if request.method == 'POST': """ Add a note to a application """
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]))
form = NoteForm() if check_permissions(request.user) == HR_ADMIN:
return render_to_response('hr/applications/add_note.html', locals(), context_instance=RequestContext(request)) 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): def add_message(request, applicationid):
if request.method == 'POST': """ Send a message to the end user and note it on the application """
obj = Audit(application=Application.objects.get(id=applicationid), user=request.user, event=AUDIT_EVENT_MESSAGE) app = get_object_or_404(Application, id=applicationid)
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]))
form = NoteForm() if check_permissions(request.user, app):
return render_to_response('hr/applications/add_message.html', locals(), context_instance=RequestContext(request)) 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 @login_required
def reject_application(request, applicationid): def reject_application(request, applicationid):
if request.method == 'POST': """ Reject the application and notify the user """
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]))
form = NoteForm() if check_permissions(request.user) == HR_ADMIN:
return render_to_response('hr/applications/reject.html', locals(), context_instance=RequestContext(request)) 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 @login_required
def accept_application(request, applicationid): def accept_application(request, applicationid):
if request.method == 'POST': """ Accept the application and notify the user """
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]))
form = NoteForm() if check_permissions(request.user) == HR_ADMIN:
return render_to_response('hr/applications/accept.html', locals(), context_instance=RequestContext(request)) 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))

View File

@@ -23,9 +23,9 @@
{% else %} {% else %}
<a href="{% url hr.views.update_application app.id 0 %}">Withdraw Application</a>,&nbsp; <a href="{% url hr.views.update_application app.id 0 %}">Withdraw Application</a>,&nbsp;
{% endif %} {% endif %}
<a href="{% url hr.views.add_message app.id %}">Add Message</a>,
{% if hrstaff %} {% if hrstaff %}
<a href="{% url hr.views.add_note app.id %}">Add Note</a>,&nbsp; <a href="{% url hr.views.add_note app.id %}">Add Staff Note</a>,&nbsp;
<a href="{% url hr.views.add_message app.id %}">Send Message to Applicant</a>,
{% if app.status < 2 or app.status = 4 %} {% if app.status < 2 or app.status = 4 %}
<a href="{% url hr.views.reject_application app.id %}">Reject Application</a>,&nbsp; <a href="{% url hr.views.reject_application app.id %}">Reject Application</a>,&nbsp;
{% ifequal app.blacklisted 0 %} {% ifequal app.blacklisted 0 %}
@@ -45,7 +45,7 @@
{% if audit %} {% if audit %}
<h3>Event Log</h3> <h3>Event Log</h3>
<table> <table>
<tr><th>Event Type</th><th>Changed By</th><th>Changed Date</th><th>Event Details</th></tr> <tr><th>Event Type</th><th>User</th><th>Date</th><th>Event Details</th></tr>
{% for a in audit %} {% for a in audit %}
<tr><td>{{ a.get_event_display }}</td><td>{{ a.user }}</td><td>{{ a.date }}</td><td>{{ a.text }}</td></tr> <tr><td>{{ a.get_event_display }}</td><td>{{ a.user }}</td><td>{{ a.date }}</td><td>{{ a.text }}</td></tr>
{% endfor %} {% endfor %}
@@ -74,16 +74,17 @@
{% if hrstaff %} {% if hrstaff %}
<h3>EVE Characters</h3> <h3>EVE Characters</h3>
<ul> <ul>
{% for acc in eveacc %} {% for acc in app.user.eveaccount_set.all %}
{% for char in acc.characters.all %} {% for char in acc.characters.all %}
<li><a href="{% url sso.views.characters char.id %}">{{ char.name }}</a> - {{ char.corporation }} / {{ char.corporation.alliance }} - {{ char.balance|intcomma }} ISK, {{ char.total_sp|intcomma }} SP <button type="button" onclick="CCPEVE.showInfo('1377//{{ char.id }}')">Show In Eve</button> - <a href="https://gate.eveonline.com/Profile/{{ char.name }}/">EveGate Profile</a></li> <li><a href="{% url sso.views.characters char.id %}">{{ char.name }}</a> - {{ char.corporation }} / {{ char.corporation.alliance }} - {{ char.balance|intcomma }} ISK, {{ char.total_sp|intcomma }} SP <button type="button" onclick="CCPEVE.showInfo('1377//{{ char.id }}')">Show In Eve</button> - <a href="https://gate.eveonline.com/Profile/{{ char.name }}/">EveGate Profile</a></li>
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
</ul> </ul>
{% if app.user.redditaccount_set.all %}
<h3>Reddit Accounts</h3> <h3>Reddit Accounts</h3>
<ul> <ul>
{% for acc in redditacc %} {% for acc in app.user.redditaccount_set.all %}
<li><a href="http://reddit.com/user/{{ acc.username }}/">{{ acc.username }}</a>{% if acc.validated %} - Validated{%else %} - <b>NOT VALIDATED</b>{% endif %} - {{ acc.date_created }}</li> <li><a href="http://reddit.com/user/{{ acc.username }}/">{{ acc.username }}</a>{% if acc.validated %} - Validated{%else %} - <b>NOT VALIDATED</b>{% endif %} - {{ acc.date_created }}</li>
{% endfor %} {% endfor %}
</ul> </ul>
@@ -102,4 +103,5 @@
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %} {% endif %}
{% endif %}
{% endblock %} {% endblock %}