Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/help/positions/apply.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
====================
Apply for a position
====================

Active members can now see a list of open leadership positions created by the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The title of the page is "Apply for a position", so maybe we should mention that they can do that here as well? Something like:

Active members can now view and apply for leadership opportunities online. New positions are posted regularly by the Executive Board.

Executive Board.

Viewing Positions
-----------------
To view a list of open positions, go to the "Members" dropdown and find the
"Open Positions" link. Clicking that link will bring you to a list of positions
that are currently looking for interested members.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
that are currently looking for interested members.
that we are currently looking for candidates for.


.. hint:
You can click the name of a position to view more information

Applying
--------
Depending on how the Executive board has created the position, you can do one of
two things to express your interest. If they have created a form for interested
members, there will be a green "Apply" button that will take you to the form. If
they haven't created a form, look at the position description for more
information.

`Last modified: 13 December 2021`
Empty file added docs/help/positions/create.rst
Empty file.
9 changes: 9 additions & 0 deletions docs/help/user-guides.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,19 @@ Training
training/request-pit
training/training-records


Slack
^^^^^

.. toctree::
:maxdepth: 1

report-slack

Positions
^^^^^^^^^

.. toctree::
:maxdepth: 1
positions/apply
positions/create
4 changes: 4 additions & 0 deletions events/views/indices.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from events.models import BaseEvent, Workshop, CrewAttendanceRecord
from helpers.challenges import is_officer
from pages.models import OnboardingScreen, OnboardingRecord
from positions.models import Position


# FRONT 3 PAGES
Expand Down Expand Up @@ -80,6 +81,9 @@ def admin(request, msg=None):
datetime_end__gte=(now - datetime.timedelta(hours=3))).distinct()
context['selfcrew_events'] = selfcrew_events

open_positions = Position.objects.filter(closes__gte=timezone.now()).count()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also excludes listings that don't have applications that close

context['open_positions'] = open_positions

return render(request, 'admin.html', context)


Expand Down
1 change: 1 addition & 0 deletions lnldb/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ def from_runtime(*x):
'api',
'rt',
'slack',
'positions',

'bootstrap3',
'crispy_forms',
Expand Down
1 change: 1 addition & 0 deletions lnldb/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
url(r'^mdm/', include(('devices.urls.mdm', 'mdm'), namespace="mdm")),
url(r'^support/', include(('rt.urls', 'support'), namespace='support')),
url(r'', include(('pages.urls', 'pages'), namespace='pages')),
url(r'^db/positions/', include('positions.urls', 'positions')),

# special urls
url(r'^db/$', db_home, name="home"),
Expand Down
Empty file added positions/__init__.py
Empty file.
7 changes: 7 additions & 0 deletions positions/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.contrib import admin

from .models import Position

# Register your models here.

admin.site.register(Position)
6 changes: 6 additions & 0 deletions positions/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class PositionsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'positions'
14 changes: 14 additions & 0 deletions positions/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from django import forms
from .models import Position
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit

class UpdateCreatePosition(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.add_input(Submit('submit', 'Submit'))
class Meta:
model = Position
fields = ('name', 'description', 'position_start', 'position_end',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • For the description field, you may want to consider using something like the Pagedown widget.
  • For the closes field you should definitely use the SplitDateTimeField.
  • reports_to should probably be a AutoCompleteSelectField.

There are tons of examples in other modules that you can look at if you need to.

'closes', 'reports_to', 'application_form')
28 changes: 28 additions & 0 deletions positions/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 3.1.13 on 2021-11-03 20:49

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),
]

operations = [
migrations.CreateModel(
name='Position',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32, verbose_name='Position Name')),
('description', models.TextField(verbose_name='Position Description')),
('position_start', models.DateField(verbose_name='Term Start')),
('position_end', models.DateField(verbose_name='Term End')),
('reports_to', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
37 changes: 37 additions & 0 deletions positions/migrations/0002_auto_20211104_1125.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Generated by Django 3.1.13 on 2021-11-04 15:25

import datetime
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('positions', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='position',
name='application_form',
field=models.CharField(default='', max_length=128, verbose_name='Link to external application form'),
preserve_default=False,
),
migrations.AddField(
model_name='position',
name='closes',
field=models.DateTimeField(default=datetime.datetime.now, verbose_name='Applications Close'),
preserve_default=False,
),
migrations.CreateModel(
name='ApplicationInstance',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('applicant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('position', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='positions.position')),
],
),
]
23 changes: 23 additions & 0 deletions positions/migrations/0003_auto_20211111_1309.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.1.13 on 2021-11-11 18:09

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('positions', '0002_auto_20211104_1125'),
]

operations = [
migrations.AlterField(
model_name='position',
name='closes',
field=models.DateField(blank=True, null=True, verbose_name='Applications Close'),
),
migrations.AlterField(
model_name='position',
name='name',
field=models.CharField(max_length=64, verbose_name='Position Name'),
),
]
21 changes: 21 additions & 0 deletions positions/migrations/0004_auto_20211111_1419.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated by Django 3.1.13 on 2021-11-11 19:19

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('positions', '0003_auto_20211111_1309'),
]

operations = [
migrations.AlterField(
model_name='position',
name='reports_to',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]
17 changes: 17 additions & 0 deletions positions/migrations/0005_auto_20211112_1115.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 3.1.13 on 2021-11-12 16:15

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('positions', '0004_auto_20211111_1419'),
]

operations = [
migrations.AlterModelOptions(
name='position',
options={'permissions': [('apply', 'Can apply for positions')]},
),
]
16 changes: 16 additions & 0 deletions positions/migrations/0006_delete_applicationinstance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Generated by Django 3.1.13 on 2021-11-12 17:00

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('positions', '0005_auto_20211112_1115'),
]

operations = [
migrations.DeleteModel(
name='ApplicationInstance',
),
]
23 changes: 23 additions & 0 deletions positions/migrations/0007_auto_20211114_1403.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.1.13 on 2021-11-14 19:03

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('positions', '0006_delete_applicationinstance'),
]

operations = [
migrations.AlterField(
model_name='position',
name='application_form',
field=models.URLField(max_length=128, verbose_name='Link to external application form'),
),
migrations.AlterField(
model_name='position',
name='closes',
field=models.DateTimeField(blank=True, null=True, verbose_name='Applications Close'),
),
]
18 changes: 18 additions & 0 deletions positions/migrations/0008_auto_20211213_1256.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.1.13 on 2021-12-13 17:56

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('positions', '0007_auto_20211114_1403'),
]

operations = [
migrations.AlterField(
model_name='position',
name='application_form',
field=models.URLField(blank=True, max_length=128, null=True, verbose_name='Link to external application form'),
),
]
Empty file.
38 changes: 38 additions & 0 deletions positions/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone

import datetime

# Create your models here.

class Position(models.Model):
"""
Describes a leadership position for a specific time. A new position instance
should be created every time one needs to be filled.
"""
name = models.CharField(verbose_name="Position Name", max_length=64,
null=False, blank=False)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is redundant. Null and blank are False by default so they technically don't need to be specified. Not necessarily a problem, just reads a bit nicer in my opinion without them.

description = models.TextField(verbose_name="Position Description",
null=False, blank=False)
position_start = models.DateField(verbose_name="Term Start", null=False,
blank=False)
position_end = models.DateField(verbose_name="Term End", null=False,
blank=False)
reports_to = models.ForeignKey(get_user_model(), on_delete=models.CASCADE,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a user were to be deleted (unlikely, but possible), on_delete=models.CASCADE indicates that this object would be too. You may want to consider using something different here like SET_NULL.

blank=True, null=True)
closes = models.DateTimeField(verbose_name="Applications Close", null=True,
blank=True)
application_form = models.URLField(verbose_name="Link to external application form", null=True, blank=True, max_length=128)

def __str__(self):
return f"{self.name}"

class Meta:
permissions = [
('apply', 'Can apply for positions')
]

def is_open(self):
return self.closes >= timezone.now()

Loading