mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-02-10 17:16:22 +01:00
Restructure Alliance Auth package (#867)
* Refactor allianceauth into its own package * Add setup * Add missing default_app_config declarations * Fix timerboard namespacing * Remove obsolete future imports * Remove py2 mock support * Remove six * Add experimental 3.7 support and multiple Dj versions * Remove python_2_unicode_compatible * Add navhelper as local package * Update requirements
This commit is contained in:
1
allianceauth/hrapplications/__init__.py
Normal file
1
allianceauth/hrapplications/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
default_app_config = 'allianceauth.hrapplications.apps.HRApplicationsConfig'
|
||||
23
allianceauth/hrapplications/admin.py
Executable file
23
allianceauth/hrapplications/admin.py
Executable file
@@ -0,0 +1,23 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Application, ApplicationChoice, ApplicationComment, ApplicationForm, ApplicationQuestion, \
|
||||
ApplicationResponse
|
||||
|
||||
|
||||
class ChoiceInline(admin.TabularInline):
|
||||
model = ApplicationChoice
|
||||
extra = 0
|
||||
verbose_name_plural = 'Choices (optional)'
|
||||
verbose_name= 'Choice'
|
||||
|
||||
class QuestionAdmin(admin.ModelAdmin):
|
||||
fieldsets = [
|
||||
(None, {'fields': ['title', 'help_text']}),
|
||||
]
|
||||
inlines = [ChoiceInline]
|
||||
|
||||
admin.site.register(Application)
|
||||
admin.site.register(ApplicationComment)
|
||||
admin.site.register(ApplicationQuestion, QuestionAdmin)
|
||||
admin.site.register(ApplicationForm)
|
||||
admin.site.register(ApplicationResponse)
|
||||
6
allianceauth/hrapplications/apps.py
Normal file
6
allianceauth/hrapplications/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class HRApplicationsConfig(AppConfig):
|
||||
name = 'allianceauth.hrapplications'
|
||||
label = 'hrapplications'
|
||||
28
allianceauth/hrapplications/auth_hooks.py
Normal file
28
allianceauth/hrapplications/auth_hooks.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from allianceauth.services.hooks import MenuItemHook, UrlHook
|
||||
|
||||
from allianceauth import hooks
|
||||
from allianceauth.hrapplications import urls
|
||||
|
||||
|
||||
class ApplicationsMenu(MenuItemHook):
|
||||
def __init__(self):
|
||||
MenuItemHook.__init__(self,
|
||||
'Applications',
|
||||
'fa fa-file-o fa-fw grayiconecolor',
|
||||
'hrapplications:index',
|
||||
navactive=['hrapplications:'])
|
||||
|
||||
|
||||
@hooks.register('menu_item_hook')
|
||||
def register_menu():
|
||||
return ApplicationsMenu()
|
||||
|
||||
|
||||
class ApplicationsUrls(UrlHook):
|
||||
def __init__(self):
|
||||
UrlHook.__init__(self, urls, 'hrapplications', r'^hr/')
|
||||
|
||||
|
||||
@hooks.register('url_hook')
|
||||
def register_url():
|
||||
return ApplicationsUrls()
|
||||
10
allianceauth/hrapplications/forms.py
Executable file
10
allianceauth/hrapplications/forms.py
Executable file
@@ -0,0 +1,10 @@
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class HRApplicationCommentForm(forms.Form):
|
||||
comment = forms.CharField(widget=forms.Textarea, required=False, label=_("Comment"))
|
||||
|
||||
|
||||
class HRApplicationSearchForm(forms.Form):
|
||||
search_string = forms.CharField(max_length=254, required=True, label=_("Search String"))
|
||||
127
allianceauth/hrapplications/migrations/0001_initial.py
Normal file
127
allianceauth/hrapplications/migrations/0001_initial.py
Normal file
@@ -0,0 +1,127 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-05 21:39
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('eveonline', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Application',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('approved', models.NullBooleanField(default=None)),
|
||||
('created', models.DateTimeField(auto_now_add=True)),
|
||||
],
|
||||
options={
|
||||
'permissions': (('approve_application', 'Can approve applications'), ('reject_application', 'Can reject applications'), ('view_apis', 'Can view applicant APIs')),
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ApplicationComment',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('text', models.TextField()),
|
||||
('created', models.DateTimeField(auto_now_add=True)),
|
||||
('application', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='hrapplications.Application')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ApplicationForm',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('corp', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='eveonline.EveCorporationInfo')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ApplicationQuestion',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=254)),
|
||||
('help_text', models.CharField(blank=True, max_length=254, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ApplicationResponse',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('answer', models.TextField()),
|
||||
('application', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='hrapplications.Application')),
|
||||
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hrapplications.ApplicationQuestion')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='HRApplication',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('character_name', models.CharField(default=b'', max_length=254)),
|
||||
('full_api_id', models.CharField(default=b'', max_length=254)),
|
||||
('full_api_key', models.CharField(default=b'', max_length=254)),
|
||||
('is_a_spi', models.CharField(default=b'', max_length=254)),
|
||||
('about', models.TextField(default=b'')),
|
||||
('extra', models.TextField(default=b'')),
|
||||
('approved_denied', models.NullBooleanField()),
|
||||
('corp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eveonline.EveCorporationInfo')),
|
||||
('reviewer_character', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='eveonline.EveCharacter')),
|
||||
('reviewer_inprogress_character', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='inprogress_character', to='eveonline.EveCharacter')),
|
||||
('reviewer_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='review_user', to=settings.AUTH_USER_MODEL)),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='HRApplicationComment',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_on', models.DateTimeField(auto_now_add=True, null=True)),
|
||||
('comment', models.CharField(default=b'', max_length=254)),
|
||||
('application', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hrapplications.HRApplication')),
|
||||
('commenter_character', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eveonline.EveCharacter')),
|
||||
('commenter_user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='applicationform',
|
||||
name='questions',
|
||||
field=models.ManyToManyField(to='hrapplications.ApplicationQuestion'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='application',
|
||||
name='form',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='applications', to='hrapplications.ApplicationForm'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='application',
|
||||
name='reviewer',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='application',
|
||||
name='reviewer_character',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='eveonline.EveCharacter'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='application',
|
||||
name='user',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='applications', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='applicationresponse',
|
||||
unique_together=set([('question', 'application')]),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='application',
|
||||
unique_together=set([('form', 'user')]),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.4 on 2017-08-23 19:46
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrapplications', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ApplicationChoice',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('choice_text', models.CharField(max_length=200, verbose_name='Choice')),
|
||||
],
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='applicationquestion',
|
||||
name='title',
|
||||
field=models.CharField(max_length=254, verbose_name='Question'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='applicationchoice',
|
||||
name='question',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='choices', to='hrapplications.ApplicationQuestion'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,50 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrapplications', '0002_choices_for_questions'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='hrapplication',
|
||||
name='about',
|
||||
field=models.TextField(default=''),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='hrapplication',
|
||||
name='character_name',
|
||||
field=models.CharField(default='', max_length=254),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='hrapplication',
|
||||
name='extra',
|
||||
field=models.TextField(default=''),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='hrapplication',
|
||||
name='full_api_id',
|
||||
field=models.CharField(default='', max_length=254),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='hrapplication',
|
||||
name='full_api_key',
|
||||
field=models.CharField(default='', max_length=254),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='hrapplication',
|
||||
name='is_a_spi',
|
||||
field=models.CharField(default='', max_length=254),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='hrapplicationcomment',
|
||||
name='comment',
|
||||
field=models.CharField(default='', max_length=254),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-27 03:29
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
import sortedm2m.fields
|
||||
from sortedm2m.operations import AlterSortedManyToManyField
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrapplications', '0003_make_strings_more_stringy'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
AlterSortedManyToManyField(
|
||||
model_name='applicationform',
|
||||
name='questions',
|
||||
field=sortedm2m.fields.SortedManyToManyField(help_text=None, to='hrapplications.ApplicationQuestion'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,64 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.2 on 2017-06-08 02:54
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def delete_permissions(apps, schema_editor):
|
||||
HRApplication = apps.get_model('hrapplications', 'HRApplication')
|
||||
HRApplicationComment = apps.get_model('hrapplications', 'HRApplicationComment')
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
Permission = apps.get_model('auth', 'Permission')
|
||||
ct1 = ContentType.objects.get_for_model(HRApplication)
|
||||
ct2 = ContentType.objects.get_for_model(HRApplicationComment)
|
||||
Permission.objects.filter(content_type__in=[ct1, ct2]).delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrapplications', '0004_sorted_questions'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='hrapplication',
|
||||
name='corp',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='hrapplication',
|
||||
name='reviewer_character',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='hrapplication',
|
||||
name='reviewer_inprogress_character',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='hrapplication',
|
||||
name='reviewer_user',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='hrapplication',
|
||||
name='user',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='hrapplicationcomment',
|
||||
name='application',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='hrapplicationcomment',
|
||||
name='commenter_character',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='hrapplicationcomment',
|
||||
name='commenter_user',
|
||||
),
|
||||
migrations.RunPython(delete_permissions, migrations.RunPython.noop),
|
||||
migrations.DeleteModel(
|
||||
name='HRApplication',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='HRApplicationComment',
|
||||
),
|
||||
]
|
||||
0
allianceauth/hrapplications/migrations/__init__.py
Normal file
0
allianceauth/hrapplications/migrations/__init__.py
Normal file
86
allianceauth/hrapplications/models.py
Executable file
86
allianceauth/hrapplications/models.py
Executable file
@@ -0,0 +1,86 @@
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from sortedm2m.fields import SortedManyToManyField
|
||||
|
||||
from allianceauth.eveonline.models import EveCharacter
|
||||
from allianceauth.eveonline.models import EveCorporationInfo
|
||||
|
||||
|
||||
class ApplicationQuestion(models.Model):
|
||||
title = models.CharField(max_length=254, verbose_name='Question')
|
||||
help_text = models.CharField(max_length=254, blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return "Question: " + self.title
|
||||
|
||||
|
||||
class ApplicationChoice(models.Model):
|
||||
question = models.ForeignKey(ApplicationQuestion,on_delete=models.CASCADE,related_name="choices")
|
||||
choice_text = models.CharField(max_length=200, verbose_name='Choice')
|
||||
|
||||
def __str__(self):
|
||||
return self.choice_text
|
||||
|
||||
class ApplicationForm(models.Model):
|
||||
questions = SortedManyToManyField(ApplicationQuestion)
|
||||
corp = models.OneToOneField(EveCorporationInfo)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.corp)
|
||||
|
||||
|
||||
class Application(models.Model):
|
||||
form = models.ForeignKey(ApplicationForm, on_delete=models.CASCADE, related_name='applications')
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='applications')
|
||||
approved = models.NullBooleanField(blank=True, null=True, default=None)
|
||||
reviewer = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)
|
||||
reviewer_character = models.ForeignKey(EveCharacter, on_delete=models.SET_NULL, blank=True, null=True)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.user) + " Application To " + str(self.form)
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
('approve_application', 'Can approve applications'), ('reject_application', 'Can reject applications'),
|
||||
('view_apis', 'Can view applicant APIs'),)
|
||||
unique_together = ('form', 'user')
|
||||
|
||||
@property
|
||||
def main_character(self):
|
||||
return self.user.profile.main_character
|
||||
|
||||
@property
|
||||
def characters(self):
|
||||
return [o.character for o in self.user.character_ownerships.all()]
|
||||
|
||||
@property
|
||||
def reviewer_str(self):
|
||||
if self.reviewer_character:
|
||||
return str(self.reviewer_character)
|
||||
elif self.reviewer:
|
||||
return "User " + str(self.reviewer)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class ApplicationResponse(models.Model):
|
||||
question = models.ForeignKey(ApplicationQuestion, on_delete=models.CASCADE)
|
||||
application = models.ForeignKey(Application, on_delete=models.CASCADE, related_name='responses')
|
||||
answer = models.TextField()
|
||||
|
||||
def __str__(self):
|
||||
return str(self.application) + " Answer To " + str(self.question)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('question', 'application')
|
||||
|
||||
|
||||
class ApplicationComment(models.Model):
|
||||
application = models.ForeignKey(Application, on_delete=models.CASCADE, related_name='comments')
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
text = models.TextField()
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.user) + " comment on " + str(self.application)
|
||||
@@ -0,0 +1,27 @@
|
||||
{% extends "registered/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}Choose a Corp{% endblock %}
|
||||
{% block page_title %}{% trans "Choose a Corp" %}{% endblock page_title %}
|
||||
{% block content %}
|
||||
<div class="col-lg-12">
|
||||
<h1 class="page-header text-center">{% trans "Choose a Corp" %}</h1>
|
||||
{% if choices %}
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">{% trans "Available Corps" %}</div>
|
||||
<table class="table table-responsive">
|
||||
{% for choice in choices %}
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'hrapplications:create_view' choice.0 %}" class="btn btn-primary" title="Apply">{{ choice.1 }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-danger">{% trans "No corps are accepting applications at this time." %}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock content %}
|
||||
@@ -0,0 +1,37 @@
|
||||
{% extends "registered/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}Apply To {{ corp.corporation_name }}{% endblock title %}
|
||||
{% block page_title %}{% trans "Apply To" %} {{ corp.corporation_name }}{% endblock page_title %}
|
||||
{% block content %}
|
||||
<div class="col-lg-12">
|
||||
<h1 class="page-header text-center">{% trans "Apply To" %} {{ corp.corporation_name }}</h1>
|
||||
<div class="container-fluid">
|
||||
<div class="col-md-4 col-md-offset-4">
|
||||
<div class="row">
|
||||
<form class="form-signin">
|
||||
{% csrf_token %}
|
||||
{% for question in questions %}
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="id_{{ question.pk }}">{{ question.title }}</label>
|
||||
<div class=" ">
|
||||
{% if question.help_text %}
|
||||
<div cass="text-center">{{ question.help_text }}</div>
|
||||
{% endif %}
|
||||
{% for choice in question.choices.all %}
|
||||
<input type="radio" name="{{ question.pk }}" id="id_{{ question.pk }}" value="{{ choice.choice_text }}" />
|
||||
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
|
||||
{% empty %}
|
||||
<textarea class="form-control" cols="30" id="id_{{ question.pk }}" name="{{ question.pk }}" rows="4"></textarea>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit" formmethod="post">{% trans "Submit" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,198 @@
|
||||
{% extends "registered/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}Alliance Auth{% endblock %}
|
||||
|
||||
{% block page_title %}{% trans "HR Application Management" %}{% endblock page_title %}
|
||||
{% block extra_css %}{% endblock extra_css %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-lg-12">
|
||||
<h1 class="page-header text-center">{% trans "Personal Applications" %}
|
||||
<div class="text-right">
|
||||
{% if create %}
|
||||
<a href="{% url 'hrapplications:create_view' %}">
|
||||
<button type="button" class="btn btn-success">{% trans "Create Application" %}</button>
|
||||
</a>
|
||||
{% else %}
|
||||
<button type="button" class="btn btn-success" disabled>{% trans "Create Application" %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</h1>
|
||||
{% if personal_apps %}
|
||||
<div class="panel panel-default">
|
||||
<table class="table table-condensed">
|
||||
<tr>
|
||||
<th class="text-center">{% trans "Username" %}</th>
|
||||
<th class="text-center">{% trans "Corporation" %}
|
||||
<th class="text-center">{% trans "Status" %}</th>
|
||||
<th class="text-center">{% trans "Actions" %}</th>
|
||||
</tr>
|
||||
{% for personal_app in personal_apps %}
|
||||
<tr>
|
||||
<td class="text-center">{{ personal_app.user.username }}</td>
|
||||
<td class="text-center">{{ personal_app.form.corp.corporation_name }}</td>
|
||||
<td class="text-center">
|
||||
{% if personal_app.approved == None %}
|
||||
<div class="label label-warning">{% trans "Pending" %}</div>
|
||||
{% elif personal_app.approved == True %}
|
||||
<div class="label label-success">{% trans "Approved" %}</div>
|
||||
{% else %}
|
||||
<div class="label label-danger">{% trans "Rejected" %}</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'hrapplications:personal_view' personal_app.id %}"
|
||||
class="btn btn-primary">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
|
||||
{% if personal_app.approved == None %}
|
||||
<a href="{% url 'hrapplications:personal_removal' personal_app.id %}"
|
||||
class="btn btn-danger">
|
||||
<span class="glyphicon glyphicon-remove"></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if perms.auth.human_resources %}
|
||||
<h1 class="page-header text-center">{% trans "Application Management" %}
|
||||
<div class="text-right">
|
||||
<!-- Button trigger modal -->
|
||||
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#myModal">
|
||||
{% trans "Search Applications" %}
|
||||
</button>
|
||||
</div>
|
||||
</h1>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a data-toggle="tab" href="#pending">{% trans "Pending" %}</a></li>
|
||||
<li><a data-toggle="tab" href="#reviewed">{% trans "Reviewed" %}</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div id="pending" class="tab-pane fade in active panel panel-default">
|
||||
<div class="panel-body">
|
||||
{% if applications %}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th class="text-center">{% trans "Date" %}</th>
|
||||
<th class="text-center">{% trans "Username" %}</th>
|
||||
<th class="text-center">{% trans "Main Character" %}</th>
|
||||
<th class="text-center">{% trans "Corporation" %}</th>
|
||||
<th class="text-center">{% trans "Status" %}</th>
|
||||
<th class="text-center">{% trans "Actions" %}</th>
|
||||
</tr>
|
||||
{% for app in applications %}
|
||||
<tr>
|
||||
<td class="text-center">{{ app.created }}</td>
|
||||
<td class="text-center">{{ app.user.username }}</td>
|
||||
<td class="text-center">{{ app.main_character }}</td>
|
||||
<td class="text-center">{{ app.form.corp.corporation_name }}</td>
|
||||
<td class="text-center">
|
||||
{% if app.approved == None %}
|
||||
{% if app.reviewer_str %}
|
||||
<div class="label label-info">{% trans "Reviewer:" %} {{ app.reviewer_str }}</div>
|
||||
{% else %}
|
||||
<div class="label label-warning">{% trans "Pending" %}</div>
|
||||
{% endif %}
|
||||
{% elif app.approved == True %}
|
||||
<div class="label label-success">{% trans "Approved" %}</div>
|
||||
{% else %}
|
||||
<div class="label label-danger">{% trans "Rejected" %}</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'hrapplications:view' app.id %}"
|
||||
class="btn btn-primary">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="alert alert-warning text-center">{% trans "No pending applications." %}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div id="reviewed" class="tab-pane fade panel panel-default">
|
||||
<div class="panel-body">
|
||||
{% if finished_applications %}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th class="text-center">{% trans "Date" %}</th>
|
||||
<th class="text-center">{% trans "Username" %}</th>
|
||||
<th class="text-center">{% trans "Main Character" %}</th>
|
||||
<th class="text-center">{% trans "Corporation" %}</th>
|
||||
<th class="text-center">{% trans "Status" %}</th>
|
||||
<th class="text-center">{% trans "Actions" %}</th>
|
||||
</tr>
|
||||
{% for app in finished_applications %}
|
||||
<tr>
|
||||
<td class="text-center">{{ app.created }}</td>
|
||||
<td class="text-center">{{ app.user.username }}</td>
|
||||
<td class="text-center">{{ app.main_character }}</td>
|
||||
<td class="text-center">{{ app.form.corp.corporation_name }}</td>
|
||||
<td class="text-center">
|
||||
{% if app.approved == None %}
|
||||
{% if app.reviewer_str %}
|
||||
<div class="label label-info">{% trans "Reviewer:" %} {{ app.reviewer_str }}</div>
|
||||
{% else %}
|
||||
<div class="label label-warning">{% trans "Pending" %}</div>
|
||||
{% endif %}
|
||||
{% elif app.approved == True %}
|
||||
<div class="label label-success">{% trans "Approved" %}</div>
|
||||
{% else %}
|
||||
<div class="label label-danger">{% trans "Rejected" %}</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'hrapplications:view' app.id %}"
|
||||
class="btn btn-primary">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="alert alert-warning text-center">{% trans "No reviewed applications." %}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if perms.auth.human_resources %}
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span
|
||||
class="sr-only">{% trans "Close" %}</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel">{% trans "Application Search" %}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-signin" role="form"
|
||||
action={% url 'hrapplications:search' %} method="POST">
|
||||
{% csrf_token %}
|
||||
{{ search_form|bootstrap }}
|
||||
<br/>
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">{% trans "Search" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
@@ -0,0 +1,85 @@
|
||||
{% extends "registered/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}Alliance Auth{% endblock %}
|
||||
|
||||
{% block page_title %}HR Application Management{% endblock page_title %}
|
||||
{% block extra_css %}{% endblock extra_css %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-lg-12">
|
||||
{% if perms.auth.human_resources %}
|
||||
<h1 class="page-header text-center">{% trans "Application Search Results" %}
|
||||
<div class="text-right">
|
||||
<!-- Button trigger modal -->
|
||||
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#myModal">
|
||||
{% trans "Search Applications" %}
|
||||
</button>
|
||||
</div>
|
||||
</h1>
|
||||
<div class="container-fluid">
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th class="text-center">{% trans "Application ID" %}</th>
|
||||
<th class="text-center">{% trans "Username" %}</th>
|
||||
<th class="text-center">{% trans "Main Character" %}</th>
|
||||
<th class="text-center">{% trans "Corporation" %}</th>
|
||||
<th class="text-center">{% trans "Status" %}</th>
|
||||
<th class="text-center">{% trans "Actions" %}</th>
|
||||
</tr>
|
||||
{% for app in applications %}
|
||||
<tr>
|
||||
<td class="text-center">{{ app.id }}</td>
|
||||
<td class="text-center">{{ app.user }}</td>
|
||||
<td class="text-center">{{ app.main_character }}</td>
|
||||
<td class="text-center">{{ app.form.corp }}</td>
|
||||
<td class="text-center">
|
||||
{% if app.approved == None %}
|
||||
<div class="label label-warning">{% trans "Pending" %}</div>
|
||||
{% elif app.approved == True %}
|
||||
<div class="label label-success">{% trans "Approved" %}</div>
|
||||
{% else %}
|
||||
<div class="label label-danger">{% trans "Rejected" %}</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'hrapplications:view' app.id %}" class="btn btn-primary">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if perms.auth.human_resources %}
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span
|
||||
class="sr-only">{% trans "Close" %}</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel">{% trans "Application Search" %}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-signin" role="form"
|
||||
action={% url 'hrapplications:search' %} method="POST">
|
||||
{% csrf_token %}
|
||||
{{ search_form|bootstrap }}
|
||||
<br/>
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">{% trans "Search" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
164
allianceauth/hrapplications/templates/hrapplications/view.html
Normal file
164
allianceauth/hrapplications/templates/hrapplications/view.html
Normal file
@@ -0,0 +1,164 @@
|
||||
{% extends "registered/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load bootstrap %}
|
||||
{% load i18n %}
|
||||
{% load eveonline_extras %}
|
||||
|
||||
{% block title %}Alliance Auth - {% trans "View Application" %}{% endblock %}
|
||||
{% block page_title %}{% trans "View Application" %}{% endblock page_title %}
|
||||
{% block extra_css %}{% endblock extra_css %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-lg-12">
|
||||
<h1 class="page-header text-center">{% trans "View Application" %}</h1>
|
||||
<div class="container-fluid">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="row">
|
||||
{% if app.approved %}
|
||||
<div class="alert alert-success text-center">{% trans "Approved" %}</div>
|
||||
{% elif app.approved == False %}
|
||||
<div class="alert alert-danger text-center">{% trans "Denied" %}</div>
|
||||
{% else %}
|
||||
<div class="alert alert-warning text-center">{% trans "Pending" %}</div>
|
||||
{% endif %}
|
||||
{% if app.reviewer_str %}
|
||||
<div class="alert alert-info text-center">{% trans "Reviewer:" %} {{ app.reviewer_str }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">{% trans "Applicant" %}</div>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th class="text-center">{% trans "User" %}</th>
|
||||
<th class="text-center">{% trans "Main Character" %}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center">{{ app.user }}</td>
|
||||
<td class="text-center">{{ app.main_character }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">{% trans "Characters" %}</div>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th class="text-center"></th>
|
||||
<th class="text-center">{% trans "Name" %}</th>
|
||||
<th class="text-center">{% trans "Corp" %}</th>
|
||||
<th class="text-center">{% trans "Alliance" %}</th>
|
||||
</tr>
|
||||
{% for char in app.characters %}
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<img class="ra-avatar img-responsive img-circle"
|
||||
src="https://image.eveonline.com/Character/{{ char.character_id }}_32.jpg">
|
||||
</td>
|
||||
<td class="text-center">{{ char.character_name }}</td>
|
||||
<td class="text-center">{{ char.corporation_name }}</td>
|
||||
<td class="text-center">{{ char.alliance_name }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{% for response in responses %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">{{ response.question.title }}</div>
|
||||
<div class="alert">{{ response.answer|linebreaksbr }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if buttons %}
|
||||
{% if perms.auth.human_resources %}
|
||||
<div class="row">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">{% trans "Actions" %}</div>
|
||||
<div class="panel-body text-center">
|
||||
{% if app.approved == None %}
|
||||
{% if app.reviewer == user %}
|
||||
{% if perms.hrapplications.approve_application %}
|
||||
<a href="{% url 'hrapplications:approve' app.id %}"
|
||||
class="btn btn-success">{% trans "Approve" %}</a>
|
||||
{% endif %}
|
||||
{% if perms.hrapplications.reject_application %}
|
||||
<a href="{% url 'hrapplications:reject' app.id %}"
|
||||
class="btn btn-danger">{% trans "Reject" %}</a>
|
||||
{% endif %}
|
||||
{% if perms.hrapplications.delete_application %}
|
||||
<a href="{% url 'hrapplications:remove' app.id %}"
|
||||
class="btn btn-danger">{% trans "Delete" %}</a>
|
||||
{% endif %}
|
||||
{% elif not app.reviewer %}
|
||||
<a href="{% url 'hrapplications:mark_in_progress' app.id %}"
|
||||
class="btn btn-warning">{% trans "Mark in Progress" %}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if perms.hrapplications.add_applicationcomment %}
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal"
|
||||
data-target="#myModal">{% trans "Comment" %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" role="tab" id="headingThree">
|
||||
<h4 class="panel-title">
|
||||
<a class="collapsed" data-toggle="collapse" data-parent="#accordion"
|
||||
href="#collapseThree" aria-expanded="false"
|
||||
aria-controls="collapseThree">
|
||||
{% trans 'Comments' %} ({{ comments.count }})
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapseThree" class="panel-collapse collapse" role="tabpanel"
|
||||
aria-labelledby="headingThree">
|
||||
<div class="panel-body">
|
||||
{% for comment in comments %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" role="tab" id="">
|
||||
<div class="panel-title">
|
||||
<div class="pull-right">{{ comment.created }}</div>
|
||||
<div class="pull-left">{% if comment.user.profile.main_character %}{{ comment.user.profile.main_character }}{% else %}{{ comment.user }}{% endif %}</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">{{ comment.text|linebreaks }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if perms.hrapplications.add_applicationcomment %}
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">
|
||||
<span aria-hidden="true">×</span><span class="sr-only">{% trans "Close" %}</span>
|
||||
</button>
|
||||
<h4 class="modal-title" id="myModalLabel">{% trans "Add Comment" %}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-signin" role="form" action="" method="POST">
|
||||
{% csrf_token %}
|
||||
{{ comment_form|bootstrap }}
|
||||
<br/>
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">{% trans "Add Comment" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
1
allianceauth/hrapplications/tests.py
Normal file
1
allianceauth/hrapplications/tests.py
Normal file
@@ -0,0 +1 @@
|
||||
# Create your tests here.
|
||||
31
allianceauth/hrapplications/urls.py
Normal file
31
allianceauth/hrapplications/urls.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from django.conf.urls import url
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = 'hrapplications'
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.hr_application_management_view,
|
||||
name="index"),
|
||||
url(r'^create/$', views.hr_application_create_view,
|
||||
name="create_view"),
|
||||
url(r'^create/(\d+)', views.hr_application_create_view,
|
||||
name="create_view"),
|
||||
url(r'^remove/(\w+)', views.hr_application_remove,
|
||||
name="remove"),
|
||||
url(r'view/(\w+)', views.hr_application_view,
|
||||
name="view"),
|
||||
url(r'personal/view/(\w+)', views.hr_application_personal_view,
|
||||
name="personal_view"),
|
||||
url(r'personal/removal/(\w+)',
|
||||
views.hr_application_personal_removal,
|
||||
name="personal_removal"),
|
||||
url(r'approve/(\w+)', views.hr_application_approve,
|
||||
name="approve"),
|
||||
url(r'reject/(\w+)', views.hr_application_reject,
|
||||
name="reject"),
|
||||
url(r'search/', views.hr_application_search,
|
||||
name="search"),
|
||||
url(r'mark_in_progress/(\w+)', views.hr_application_mark_in_progress,
|
||||
name="mark_in_progress"),
|
||||
]
|
||||
260
allianceauth/hrapplications/views.py
Executable file
260
allianceauth/hrapplications/views.py
Executable file
@@ -0,0 +1,260 @@
|
||||
import logging
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
from django.contrib.auth.decorators import user_passes_test
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from .models import Application
|
||||
from .models import ApplicationComment
|
||||
from .models import ApplicationForm
|
||||
from .models import ApplicationResponse
|
||||
from allianceauth.notifications import notify
|
||||
|
||||
from .forms import HRApplicationCommentForm
|
||||
from .forms import HRApplicationSearchForm
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def create_application_test(user):
|
||||
return bool(user.profile.main_character)
|
||||
|
||||
|
||||
@login_required
|
||||
def hr_application_management_view(request):
|
||||
logger.debug("hr_application_management_view called by user %s" % request.user)
|
||||
corp_applications = []
|
||||
finished_corp_applications = []
|
||||
main_char = request.user.profile.main_character
|
||||
if request.user.is_superuser:
|
||||
corp_applications = Application.objects.filter(approved=None)
|
||||
finished_corp_applications = Application.objects.exclude(approved=None)
|
||||
elif request.user.has_perm('auth.human_resources') and main_char:
|
||||
if ApplicationForm.objects.filter(corp__corporation_id=main_char.corporation_id).exists():
|
||||
app_form = ApplicationForm.objects.get(corp__corporation_id=main_char.corporation_id)
|
||||
corp_applications = Application.objects.filter(form=app_form).filter(approved=None)
|
||||
finished_corp_applications = Application.objects.filter(form=app_form).filter(approved__in=[True, False])
|
||||
logger.debug("Retrieved %s personal, %s corp applications for %s" % (
|
||||
len(request.user.applications.all()), len(corp_applications), request.user))
|
||||
context = {
|
||||
'personal_apps': request.user.applications.all(),
|
||||
'applications': corp_applications,
|
||||
'finished_applications': finished_corp_applications,
|
||||
'search_form': HRApplicationSearchForm(),
|
||||
'create': create_application_test(request.user)
|
||||
}
|
||||
return render(request, 'hrapplications/management.html', context=context)
|
||||
|
||||
|
||||
@login_required
|
||||
@user_passes_test(create_application_test)
|
||||
def hr_application_create_view(request, form_id=None):
|
||||
if form_id:
|
||||
app_form = get_object_or_404(ApplicationForm, id=form_id)
|
||||
if request.method == "POST":
|
||||
if Application.objects.filter(user=request.user).filter(form=app_form).exists():
|
||||
logger.warn("User %s attempting to duplicate application to %s" % (request.user, app_form.corp))
|
||||
else:
|
||||
application = Application(user=request.user, form=app_form)
|
||||
application.save()
|
||||
for question in app_form.questions.all():
|
||||
response = ApplicationResponse(question=question, application=application)
|
||||
response.answer = request.POST.get(str(question.pk),
|
||||
"Failed to retrieve answer provided by applicant.")
|
||||
response.save()
|
||||
logger.info("%s created %s" % (request.user, application))
|
||||
return redirect('auth_hrapplications_view')
|
||||
else:
|
||||
questions = app_form.questions.all()
|
||||
return render(request, 'hrapplications/create.html',
|
||||
context={'questions': questions, 'corp': app_form.corp})
|
||||
else:
|
||||
choices = []
|
||||
for app_form in ApplicationForm.objects.all():
|
||||
if not Application.objects.filter(user=request.user).filter(form=app_form).exists():
|
||||
choices.append((app_form.id, app_form.corp.corporation_name))
|
||||
return render(request, 'hrapplications/corpchoice.html', context={'choices': choices})
|
||||
|
||||
|
||||
@login_required
|
||||
def hr_application_personal_view(request, app_id):
|
||||
logger.debug("hr_application_personal_view called by user %s for app id %s" % (request.user, app_id))
|
||||
app = get_object_or_404(Application, pk=app_id)
|
||||
if app.user == request.user:
|
||||
context = {
|
||||
'app': app,
|
||||
'responses': ApplicationResponse.objects.filter(application=app),
|
||||
'buttons': False,
|
||||
'comments': ApplicationComment.objects.filter(application=app),
|
||||
'comment_form': HRApplicationCommentForm(),
|
||||
}
|
||||
return render(request, 'hrapplications/view.html', context=context)
|
||||
else:
|
||||
logger.warn("User %s not authorized to view %s" % (request.user, app))
|
||||
return redirect('auth_hrapplications_view')
|
||||
|
||||
|
||||
@login_required
|
||||
def hr_application_personal_removal(request, app_id):
|
||||
logger.debug("hr_application_personal_removal called by user %s for app id %s" % (request.user, app_id))
|
||||
app = get_object_or_404(Application, pk=app_id)
|
||||
if app.user == request.user:
|
||||
if app.approved is None:
|
||||
logger.info("User %s deleting %s" % (request.user, app))
|
||||
app.delete()
|
||||
else:
|
||||
logger.warn("User %s attempting to delete reviewed app %s" % (request.user, app))
|
||||
else:
|
||||
logger.warn("User %s not authorized to delete %s" % (request.user, app))
|
||||
return redirect('auth_hrapplications_view')
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required('auth.human_resources')
|
||||
def hr_application_view(request, app_id):
|
||||
logger.debug("hr_application_view called by user %s for app id %s" % (request.user, app_id))
|
||||
app = get_object_or_404(Application, pk=app_id)
|
||||
if request.method == 'POST':
|
||||
if request.user.has_perm('hrapplications.add_applicationcomment'):
|
||||
form = HRApplicationCommentForm(request.POST)
|
||||
logger.debug("Request type POST contains form valid: %s" % form.is_valid())
|
||||
if form.is_valid():
|
||||
comment = ApplicationComment()
|
||||
comment.application = app
|
||||
comment.user = request.user
|
||||
comment.text = form.cleaned_data['comment']
|
||||
comment.save()
|
||||
logger.info("Saved comment by user %s to %s" % (request.user, app))
|
||||
return redirect(hr_application_view, app_id)
|
||||
else:
|
||||
logger.warn("User %s does not have permission to add ApplicationComments" % request.user)
|
||||
return redirect(hr_application_view, app_id)
|
||||
else:
|
||||
logger.debug("Returning blank HRApplication comment form.")
|
||||
form = HRApplicationCommentForm()
|
||||
context = {
|
||||
'app': app,
|
||||
'responses': ApplicationResponse.objects.filter(application=app),
|
||||
'buttons': True,
|
||||
'comments': ApplicationComment.objects.filter(application=app),
|
||||
'comment_form': form,
|
||||
}
|
||||
return render(request, 'hrapplications/view.html', context=context)
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required('auth.human_resources')
|
||||
@permission_required('hrapplications.delete_application')
|
||||
def hr_application_remove(request, app_id):
|
||||
logger.debug("hr_application_remove called by user %s for app id %s" % (request.user, app_id))
|
||||
app = get_object_or_404(Application, pk=app_id)
|
||||
logger.info("User %s deleting %s" % (request.user, app))
|
||||
app.delete()
|
||||
notify(app.user, "Application Deleted", message="Your application to %s was deleted." % app.form.corp)
|
||||
return redirect('auth_hrapplications_view')
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required('auth.human_resources')
|
||||
@permission_required('hrapplications.approve_application')
|
||||
def hr_application_approve(request, app_id):
|
||||
logger.debug("hr_application_approve called by user %s for app id %s" % (request.user, app_id))
|
||||
app = get_object_or_404(Application, pk=app_id)
|
||||
if request.user.is_superuser or request.user == app.reviewer:
|
||||
logger.info("User %s approving %s" % (request.user, app))
|
||||
app.approved = True
|
||||
app.save()
|
||||
notify(app.user, "Application Accepted", message="Your application to %s has been approved." % app.form.corp,
|
||||
level="success")
|
||||
else:
|
||||
logger.warn("User %s not authorized to approve %s" % (request.user, app))
|
||||
return redirect('auth_hrapplications_view')
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required('auth.human_resources')
|
||||
@permission_required('hrapplications.reject_application')
|
||||
def hr_application_reject(request, app_id):
|
||||
logger.debug("hr_application_reject called by user %s for app id %s" % (request.user, app_id))
|
||||
app = get_object_or_404(Application, pk=app_id)
|
||||
if request.user.is_superuser or request.user == app.reviewer:
|
||||
logger.info("User %s rejecting %s" % (request.user, app))
|
||||
app.approved = False
|
||||
app.save()
|
||||
notify(app.user, "Application Rejected", message="Your application to %s has been rejected." % app.form.corp,
|
||||
level="danger")
|
||||
else:
|
||||
logger.warn("User %s not authorized to reject %s" % (request.user, app))
|
||||
return redirect('auth_hrapplications_view')
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required('auth.human_resources')
|
||||
def hr_application_search(request):
|
||||
logger.debug("hr_application_search called by user %s" % request.user)
|
||||
if request.method == 'POST':
|
||||
form = HRApplicationSearchForm(request.POST)
|
||||
logger.debug("Request type POST contains form valid: %s" % form.is_valid())
|
||||
if form.is_valid():
|
||||
searchstring = form.cleaned_data['search_string'].lower()
|
||||
applications = set([])
|
||||
logger.debug("Searching for application with character name %s for user %s" % (searchstring, request.user))
|
||||
app_list = []
|
||||
if request.user.is_superuser:
|
||||
app_list = Application.objects.all()
|
||||
else:
|
||||
try:
|
||||
app_list = Application.objects.filter(form__corp__corporation_id=request.user.profile.main_character.corporation_id)
|
||||
except AttributeError:
|
||||
logger.warn(
|
||||
"User %s missing main character model: unable to filter applications to search" % request.user)
|
||||
for application in app_list:
|
||||
if application.main_character:
|
||||
if searchstring in application.main_character.character_name.lower():
|
||||
applications.add(application)
|
||||
if searchstring in application.main_character.corporation_name.lower():
|
||||
applications.add(application)
|
||||
if application.main_character.alliance_name \
|
||||
and searchstring in application.main_character.alliance_name.lower():
|
||||
applications.add(application)
|
||||
for character in application.characters:
|
||||
if searchstring in character.character_name.lower():
|
||||
applications.add(application)
|
||||
if searchstring in character.corporation_name.lower():
|
||||
applications.add(application)
|
||||
if character.alliance_name and searchstring in character.alliance_name.lower():
|
||||
applications.add(application)
|
||||
if searchstring in application.user.username.lower():
|
||||
applications.add(application)
|
||||
logger.info("Found %s Applications for user %s matching search string %s" % (
|
||||
len(applications), request.user, searchstring))
|
||||
|
||||
context = {'applications': applications, 'search_form': HRApplicationSearchForm()}
|
||||
|
||||
return render(request, 'hrapplications/searchview.html', context=context)
|
||||
else:
|
||||
logger.debug("Form invalid - returning for user %s to retry." % request.user)
|
||||
context = {'applications': None, 'search_form': form}
|
||||
return render(request, 'hrapplications/searchview.html', context=context)
|
||||
|
||||
else:
|
||||
logger.debug("Returning empty search form for user %s" % request.user)
|
||||
return redirect("auth_hrapplications_view")
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required('auth.human_resources')
|
||||
def hr_application_mark_in_progress(request, app_id):
|
||||
logger.debug("hr_application_mark_in_progress called by user %s for app id %s" % (request.user, app_id))
|
||||
app = get_object_or_404(Application, pk=app_id)
|
||||
if not app.reviewer:
|
||||
logger.info("User %s marking %s in progress" % (request.user, app))
|
||||
app.reviewer = request.user
|
||||
app.reviewer_character = request.user.profile.main_character
|
||||
app.save()
|
||||
notify(app.user, "Application In Progress",
|
||||
message="Your application to %s is being reviewed by %s" % (app.form.corp, app.reviewer_str))
|
||||
else:
|
||||
logger.warn(
|
||||
"User %s unable to mark %s in progress: already being reviewed by %s" % (request.user, app, app.reviewer))
|
||||
return redirect("hrapplications:view", app_id)
|
||||
Reference in New Issue
Block a user