Skip to content

Commit

Permalink
Merge pull request #229 from RSE-Sheffield/feat/hide-inactive-rse
Browse files Browse the repository at this point in the history
Feature/Refactor: Show currently employed RSEs and Funded projects by default
  • Loading branch information
twinkarma authored Jun 27, 2024
2 parents 63a775d + 23cdb5d commit c760819
Show file tree
Hide file tree
Showing 21 changed files with 466 additions and 215 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ jobs:
sudo chmod +x /usr/local/share/geckodriver
sudo ln -s /usr/local/share/geckodriver /usr/local/bin/geckodriver
- name: Collect static files
run: |
poetry run python manage.py collectstatic
- name: Run tests and capture coverage stats
run: |
poetry run coverage run manage.py test
Expand Down
1 change: 1 addition & 0 deletions RSEAdmin/settings/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
}
)
else:
# TODO: use postgres for local dev
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
Expand Down
39 changes: 36 additions & 3 deletions rse/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ class DateRangeField(forms.Field):
Class is used to extend a text field by being able to parse the text and extract the date ranges
init function used to store min and max date for future use without querying database
If validation fails then min max date range is returned
The date string should be one of the following formats:
- "yyyy-MM-dd"
- "dd/MM/yyyy"
"""

def __init__(self, *args, **kwargs):
Expand All @@ -34,20 +39,41 @@ def to_python(self, value):

# create a list of date items (one for start and one for until)
fromuntil = value.split(' - ')

if len(fromuntil) != 2:
return [self.min_date, self.max_date]

try:
date_from = datetime.strptime(fromuntil[0], '%d/%m/%Y').date()
date_until = datetime.strptime(fromuntil[1], '%d/%m/%Y').date()
except ValueError:
return [self.min_date, self.max_date]
# try with different date format
try:
date_from = datetime.strptime(fromuntil[0], '%Y-%m-%d').date()
date_until = datetime.strptime(fromuntil[1], '%Y-%m-%d').date()
except ValueError:
return [self.min_date, self.max_date]

return [date_from, date_until]

def validate(self, value):
if len(value) != 2:
forms.ValidationError('Date range is in wrong format')


class UsersFilterForm(forms.Form):
"""
Class represents a filter form for filtering by Active and Staff status
Values for options does not use database character keys as tables are filtered directly at client side (in the data table)
"""

active_filter = forms.ChoiceField(
choices=(('', 'All'), ('Yes', 'Yes'), ('No', 'No')),
widget=forms.Select(attrs={'class': 'form-control'}))
staff_filter = forms.ChoiceField(choices= (('', 'All'), ('Yes', 'Yes'), ('No', 'No')),
widget=forms.Select(attrs={'class': 'form-control'}))


class FilterDateRangeForm(forms.Form):
"""
Class represents a date range field using the javascript daterangepicker library.
Expand All @@ -73,7 +99,7 @@ def until_date(self):

@property
def years(self):
return FinancialYear.objects.all()
return FinancialYear.objects.all().order_by('year')


class FilterDateForm(forms.Form):
Expand Down Expand Up @@ -116,7 +142,14 @@ class FilterProjectForm(FilterDateRangeForm):
('A', 'All'),
('L', 'Funded and Review')) +
Project.STATUS_CHOICES,
widget=forms.Select(attrs={'class': 'form-control pull-right'}))
initial='F',
widget=forms.Select(attrs={'class': 'form-control pull-right'})
)

rse_in_employment = forms.ChoiceField(
choices=(('All', 'All'), ('Yes', 'Yes'), ('No', 'No')),
widget=forms.Select(attrs={'class': 'form-control pull-right'})
)
# Type cant be filtered at database level as it is a property
# type = forms.ChoiceField(choices = (('A', 'All'), ('F', 'Allocated'), ('S', 'Service')), widget=forms.Select(attrs={'class': 'form-control pull-right'}))

Expand Down
21 changes: 20 additions & 1 deletion rse/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,26 +68,45 @@ class FinancialYear(models.Model):
"""
Year represents a financial year starting in August of the year field (not an academic year of Sept to Sept).
"""

year = models.IntegerField(primary_key=True) # Must relate to a financial year
service_day_rate = models.DecimalField(max_digits=8, decimal_places=2, default=300)
""" Service day rate for the current financial year """
overheads_rate = models.DecimalField(max_digits=8, decimal_places=2, default=250)
""" Overheads rate pro rota for the current financial year """


def start_date(self) -> date:
"""Get start date of the financial year."""

return date(self.year, 8, 1)


def end_date(self) -> date:
"""Get end date of the financial year."""
return self.start_date() + timedelta(days=364)

return self.start_date() + timedelta(days=365 if self.is_leap_year == True else 364)


def date_in_financial_year(self, date: date) -> bool:
"""
Functions checks is a date is in the finical year represented
"""
return date >= self.start_date() and date <= self.end_date()


def is_leap_year(self) -> bool:
""" Check if the financial year includes a leap year (next year). """

next_year = self.year + 1

# Leap year is divisible by 4. A century leap year is not divisible by 4 but 400.
if (next_year % 4 == 0) or (next_year % 400 == 0):
return True

return False


def __str__(self) -> str:
return str(self.year)

Expand Down
115 changes: 58 additions & 57 deletions rse/templates/client.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,66 +15,67 @@
<div class ="row">

<div class="col-md-9">
<div class="box box-solid">
<div class="box-header with-border">
<h3 class="box-title"> Projects Associated with {{client.name}}</h3>

<a id="id_add_client" href="{% url 'project_new' %}?client={{ client.id }}&next={% url 'client' client.id %}" class="fa fa-plus pull-right" data-toggle="tooltip" title="" data-original-title="Create a new project for this client"></a>
</div>
<div class="box-body">

<table id="projects" class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th id="type">Type</th>
<th id="internal">Internal</th>
<th id="title">Title</th>
<th id="status">Status</th>
<th id="duration">Duration (days)</th>
<th id="fte">FTE</th>
<th id="start">Start</th>
<th id="end">End</th>
<th id="schedule">Schedule</th>
<th id="progress">Commitment</th>
<th id="progress_label"></th>
<th id="more"></th>
</tr>
</thead>
<tbody>
{% for p in projects %}
<tr>
<td>{{ p.id }}</td>
<td>{{ p.type_str }}</td>
<td><input type="checkbox" disabled {% if p.internal %}checked{% endif %}></input></td>
<td>{{ p.name }}</td>
<td><span class="label {{ p.status|projectstatuslabel }}">{{ p.get_status_display }}</span></td>
<td>{{ p.duration }}</td>
<td>{{ p.fte }}</td>
<td>{{ p.start|date:'Y-m-d' }}</td>
<td>{{ p.end|date:'Y-m-d' }}</td>
<td><span class="label {{ p.get_schedule_display|schedulestatuslabel }}">{{ p.get_schedule_display }}</span></td>
<td>
<div class="progress progress-xs {% if p.percent_allocated >= 50 and p.percent_allocated < 99.5%} progress-striped active {% endif %}">
<div class="progress-bar {% if p.percent_allocated|percent < 50 %}progress-bar-danger{% elif p.percent_allocated|percent == "100" %}progress-bar-success{%else%}progress-bar-primary{% endif %} " style="width: {{p.percent_allocated|percent}}%"></div>
</div>
</td>
<td>
<span class="badge {% if p.percent_allocated < 50 %}bg-red{% elif p.percent_allocated|percent == "100" %}bg-green{%else%}bg-light-blue{% endif %}">{{p.percent_allocated|percent}}%</span>
</td>
<td><a href="{% url 'project' p.id %}" class="btn btn-block btn-primary btn-xs">Info</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="box box-solid">
<div class="box-header with-border">
<h3 class="box-title"> Projects Associated with {{client.name}}</h3>

</div>
</div>
</div>
<a id="id_add_client" href="{% url 'project_new' %}?client={{ client.id }}&next={% url 'client' client.id %}" class="fa fa-plus pull-right" data-toggle="tooltip" title="" data-original-title="Create a new project for this client"></a>
</div>

<div class="box-body">

<table id="projects" class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th id="type">Type</th>
<th id="internal">Internal</th>
<th id="title">Title</th>
<th id="status">Status</th>
<th id="duration">Duration (days)</th>
<th id="fte">FTE</th>
<th id="start">Start</th>
<th id="end">End</th>
<th id="schedule">Schedule</th>
<th id="progress">Commitment</th>
<th id="progress_label"></th>
<th id="more"></th>
</tr>
</thead>
<tbody>
{% for p in projects %}
<tr>
<td>{{ p.id }}</td>
<td>{{ p.type_str }}</td>
<td><input type="checkbox" disabled {% if p.internal %}checked{% endif %}></input></td>
<td>{{ p.name }}</td>
<td><span class="label {{ p.status|projectstatuslabel }}">{{ p.get_status_display }}</span></td>
<td>{{ p.duration }}</td>
<td>{{ p.fte }}</td>
<td>{{ p.start|date:'Y-m-d' }}</td>
<td>{{ p.end|date:'Y-m-d' }}</td>
<td><span class="label {{ p.get_schedule_display|schedulestatuslabel }}">{{ p.get_schedule_display }}</span></td>
<td>
<div class="progress progress-xs {% if p.percent_allocated >= 50 and p.percent_allocated < 99.5%} progress-striped active {% endif %}">
<div class="progress-bar {% if p.percent_allocated|percent < 50 %}progress-bar-danger{% elif p.percent_allocated|percent == "100" %}progress-bar-success{%else%}progress-bar-primary{% endif %} " style="width: {{p.percent_allocated|percent}}%"></div>
</div>
</td>
<td>
<span class="badge {% if p.percent_allocated < 50 %}bg-red{% elif p.percent_allocated|percent == "100" %}bg-green{%else%}bg-light-blue{% endif %}">{{p.percent_allocated|percent}}%</span>
</td>
<td><a href="{% url 'project' p.id %}" class="btn btn-block btn-primary btn-xs">Info</a></td>
</tr>
{% endfor %}
</tbody>
</table>

</div>
</div>
</div>

<div class="col-md-3">

<div class="box box-default">
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">Client Details</h3>
<span class="pull-right"><a href="{% url 'client_edit' client.id %}" class="text-muted"><i class="fa fa-edit"></i></a></span>
Expand All @@ -98,7 +99,7 @@ <h3 class="box-title">Client Details</h3>
</div>
</div>

<div class="box box-default">
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">Client Project Filters</h3>
<div class="box-tools pull-right">
Expand Down
62 changes: 32 additions & 30 deletions rse/templates/commitments.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@



<div class ="row">
<div class="col-md-9">
<div class ="row">
<div class="col-md-9">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab_commitment" data-toggle="tab">Commitment (RSE FTE)</a></li>
Expand All @@ -39,51 +39,53 @@
</div>
</div>


</div>
</div>

<div class="col-md-3">
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">Filter</h3>
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">Filter</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
</button>
</div>
</div>
</div>
<form method='GET' id="filter_form">
<div class="box-body">
<div class="form-group">

<label>Date range:</label>
<p><i>Will show any projects which have any time within the selected date range</i><p>
<div class="input-group">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
{{ form.filter_range }}
</div>
</br>

<label>Date range:</label>
<p><i>Will show any projects which have any time within the selected date range</i><p>
<div class="input-group">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
{{ form.filter_range }}
</div>
</br>

<label>Funding Status</label>
<p><i>Filter projects based current funding status</i></p>
{{ form.status }}

<br/><br/><br/>

<label>RSE Employment Status</label>
<p><i>Filter projects based on whether RSE is currently employed.</i></p>
{{ form.rse_in_employment }}
</br>

<label>Funding Status</label>
<p><i>Filter projects based current funding status</i></p>
{{ form.status }}
</br>

</div>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary">Apply</button>
</div> {{temp}}
</form>
</div>
</div>

</div>

</div>

</div>



{% endblock %}

{% block javascript %}
Expand Down
2 changes: 1 addition & 1 deletion rse/templates/includes/daterangepicker.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//Date Range Picker
var this_fy_start = moment().startOf('year').add(7, 'months');
var this_fy_end = moment().startOf('year').add(7, 'months').add(1, 'year').subtract(1, 'days');
$('#{{filter_form.filter_range.id_for_label}}').daterangepicker({
$('#{{ filter_form.filter_range.id_for_label }}').daterangepicker({
ranges: {
'All': [moment("{{filter_form.min_date|date:"Ymd"}}", "YYYYMMDD"), moment("{{filter_form.max_date|date:"Ymd"}}", "YYYYMMDD")],
{% for y in filter_form.years %}
Expand Down
1 change: 0 additions & 1 deletion rse/templates/projects.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ <h3 class="box-title">Filters</h3>
</div>
<div class="box-body">


<div class="form-group">
<label>Project Type</label>
<p><i>Filter projects based off RSE allocated (cost recovered projects) or service work (day rate projects)</i></p>
Expand Down
Loading

0 comments on commit c760819

Please sign in to comment.