Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
78fbdaf
Update Dasboards for finance and contracting
sandeepsajan0 Jul 15, 2022
8f17f8e
Add model for PAF reviewers roles, and manage permissions for contrac…
sandeepsajan0 Jul 15, 2022
dbac1e0
Add PAF status Change form and view with dynamic roles
sandeepsajan0 Jul 19, 2022
3e0641a
Fix Send for Approval view test
sandeepsajan0 Jul 19, 2022
7156dd8
Update users role in approval form tests
sandeepsajan0 Jul 20, 2022
bbbc11c
Add request change functionality, send to compliance mail, and added …
sandeepsajan0 Jul 22, 2022
0182cf2
fix update status permissions
sandeepsajan0 Jul 24, 2022
d43e776
Add update status form(request change option) for final approver of p…
sandeepsajan0 Jul 25, 2022
45a280a
Make comments and actions non-editable
sandeepsajan0 Jul 25, 2022
0c949c8
Fix existing tests of Final approval form
sandeepsajan0 Jul 25, 2022
4aaf300
Remove RejectionView from projects
sandeepsajan0 Aug 2, 2022
8e4c6cf
Remove RejectionForm and its tests, and Move ProjectApprovalForm from…
sandeepsajan0 Aug 2, 2022
836fcad
Update tests for FinalApproval and PAFStatus Views and forms
sandeepsajan0 Aug 3, 2022
33ca76b
resolve lint issues
sandeepsajan0 Aug 3, 2022
5afc297
Fix tests for roles by creating PafReviewerRoles via settings
sandeepsajan0 Aug 4, 2022
9cd657f
Resolve migration conflicts
sandeepsajan0 Aug 9, 2022
d796154
Fix lint issues
sandeepsajan0 Aug 9, 2022
5425836
Serve fancybox and search param js file locally
sandeepsajan0 Aug 9, 2022
98fcd01
Update Dasboards for finance and contracting
sandeepsajan0 Jul 15, 2022
436d06b
Add model for PAF reviewers roles, and manage permissions for contrac…
sandeepsajan0 Jul 15, 2022
ef81bcc
Add PAF status Change form and view with dynamic roles
sandeepsajan0 Jul 19, 2022
b11ac6b
Fix Send for Approval view test
sandeepsajan0 Jul 19, 2022
c360d3b
Update users role in approval form tests
sandeepsajan0 Jul 20, 2022
79addd5
Add request change functionality, send to compliance mail, and added …
sandeepsajan0 Jul 22, 2022
d278d1f
fix update status permissions
sandeepsajan0 Jul 24, 2022
2f94aa4
Add update status form(request change option) for final approver of p…
sandeepsajan0 Jul 25, 2022
7a04946
Make comments and actions non-editable
sandeepsajan0 Jul 25, 2022
ec00445
Fix existing tests of Final approval form
sandeepsajan0 Jul 25, 2022
1a6622e
Remove RejectionView from projects
sandeepsajan0 Aug 2, 2022
f39c937
Remove RejectionForm and its tests, and Move ProjectApprovalForm from…
sandeepsajan0 Aug 2, 2022
b4d5fb8
Update tests for FinalApproval and PAFStatus Views and forms
sandeepsajan0 Aug 3, 2022
484e0d4
resolve lint issues
sandeepsajan0 Aug 3, 2022
48c93ba
Fix tests for roles by creating PafReviewerRoles via settings
sandeepsajan0 Aug 4, 2022
5e3f9c6
Resolve migration conflicts
sandeepsajan0 Aug 9, 2022
b376202
Fix lint issues
sandeepsajan0 Aug 9, 2022
272ea89
Serve fancybox and search param js file locally
sandeepsajan0 Aug 9, 2022
96efe67
Fix editable issue and update tests accordingly
sandeepsajan0 Aug 29, 2022
e8d109e
Resolve conflicts
sandeepsajan0 Aug 29, 2022
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{% extends "base-apply.html" %}
{% load render_table from django_tables2 %}
{% load i18n static %}

{% block title %}{% trans "Dashboard" %}{% endblock %}

{% block content %}
<div class="admin-bar">
<div class="admin-bar__inner admin-bar__inner--with-button">
{% block page_header %}
<h1 class="gamma heading heading--no-margin heading--bold">{% trans "Dashboard" %}</h1>
{% endblock %}
<a href="{% url 'wagtailadmin_home' %}" class="button button--primary button--arrow-pixels-white">
{% trans "Apply admin" %}
<svg><use xlink:href="#arrow-head-pixels--solid"></use></svg>
</a>
</div>
</div>
<div class="wrapper wrapper--large wrapper--inner-space-medium">
{% if waiting_for_approval.count %}
<div id="paf-awaiting-approval" class="wrapper wrapper--bottom-space">
<h4 class="heading heading--normal">{% trans "PAF awaiting approval" %}</h4>
{% render_table waiting_for_approval.table %}
</div>
{% endif %}
</div>
{% endblock %}

{% block extra_js %}
<script src="{% static 'js/apply/url-search-params.js' %}"></script>
<script src="{% static 'js/apply/submission-filters.js' %}"></script>
<script src="{% static 'js/apply/submission-tooltips.js' %}"></script>
<script src="{% static 'js/apply/tabs.js' %}"></script>
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ <h4 class="heading heading--normal">{% trans "Active Invoices" %}</h4>
{% trans "No Active Invoices" %}
{% endif %}
</div>

{% if waiting_for_approval.count %}
<div id="paf-awaiting-approval" class="wrapper wrapper--bottom-space">
<h4 class="heading heading--normal">{% trans "PAF awaiting approval" %}</h4>
{% render_table waiting_for_approval.table %}
</div>
{% endif %}
</div>
{% endblock %}

Expand Down
6 changes: 3 additions & 3 deletions hypha/apply/dashboard/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
RESUBMITTED,
SUBMITTED,
)
from hypha.apply.projects.models.project import COMMITTED
from hypha.apply.projects.models.project import WAITING_FOR_APPROVAL
from hypha.apply.projects.tests.factories import InvoiceFactory, ProjectFactory
from hypha.apply.review.tests.factories import ReviewFactory, ReviewOpinionFactory
from hypha.apply.users.groups import APPROVER_GROUP_NAME
Expand Down Expand Up @@ -135,13 +135,13 @@ def test_doesnt_show_active_invoices_when_not_mine(self):
self.assertNotContains(response, "Active Invoices")

def test_non_project_approver_cannot_see_projects_awaiting_review_stats_or_table(self):
ProjectFactory(is_locked=True, status=COMMITTED)
ProjectFactory(is_locked=False, status=WAITING_FOR_APPROVAL)

response = self.get_page()
self.assertNotContains(response, "Projects awaiting approval")

def test_project_approver_can_see_projects_awaiting_review_stats_or_table(self):
ProjectFactory(is_locked=True, status=COMMITTED)
ProjectFactory(is_locked=False, status=WAITING_FOR_APPROVAL)

user = StaffFactory()
user.groups.add(GroupFactory(name=APPROVER_GROUP_NAME))
Expand Down
42 changes: 41 additions & 1 deletion hypha/apply/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def projects_to_approve(self):
'table': None,
}

to_approve = Project.objects.in_approval().for_table()
to_approve = Project.objects.waiting_for_approval().for_table()

return {
'count': to_approve.count(),
Expand Down Expand Up @@ -160,6 +160,7 @@ def get_context_data(self, **kwargs):

context.update({
'active_invoices': self.active_invoices(),
'waiting_for_approval': self.waiting_for_approval(),
})

return context
Expand All @@ -175,6 +176,19 @@ def active_invoices(self):
'table': InvoiceDashboardTable(invoices),
}

def waiting_for_approval(self):
if not self.request.user.is_finance:
return {
'count': None,
'table': None,
}

to_paf_approve = Project.objects.waiting_for_approval().for_table()
return {
'count': to_paf_approve.count(),
'table': ProjectsDashboardTable(data=to_paf_approve),
}


class ReviewerDashboardView(MyFlaggedMixin, MySubmissionContextMixin, TemplateView):
template_name = 'dashboard/reviewer_dashboard.html'
Expand Down Expand Up @@ -261,6 +275,31 @@ def partner_submissions(self, user, submissions):
return partner_submissions, partner_submissions_table


class ContractingDashboardView(MyFlaggedMixin, TemplateView):
template_name = 'dashboard/contracting_dashboard.html'

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
'waiting_for_approval': self.waiting_for_approval()
})

return context

def waiting_for_approval(self):
if not self.request.user.is_contracting:
return {
'count': None,
'table': None,
}

to_paf_approve = Project.objects.waiting_for_approval().for_table()
return {
'count': to_paf_approve.count(),
'table': ProjectsDashboardTable(data=to_paf_approve),
}


class CommunityDashboardView(MySubmissionContextMixin, TemplateView):
template_name = 'dashboard/community_dashboard.html'

Expand Down Expand Up @@ -341,3 +380,4 @@ class DashboardView(ViewDispatcher):
community_view = CommunityDashboardView
applicant_view = ApplicantDashboardView
finance_view = FinanceDashboardView
contracting_view = ContractingDashboardView
2 changes: 2 additions & 0 deletions hypha/apply/funds/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from hypha.apply.categories.admin import CategoryAdmin, MetaTermAdmin
from hypha.apply.determinations.admin import DeterminationFormAdmin
from hypha.apply.funds.models import ReviewerRole, ScreeningStatus
from hypha.apply.projects.admin import ProjectApprovalFormAdmin
from hypha.apply.review.admin import ReviewFormAdmin
from hypha.apply.utils.admin import ListRelatedMixin

Expand Down Expand Up @@ -210,6 +211,7 @@ class ApplyAdminGroup(ModelAdminGroup):
ApplicationFormAdmin,
ReviewFormAdmin,
DeterminationFormAdmin,
ProjectApprovalFormAdmin,
CategoryAdmin,
ScreeningStatusAdmin,
ReviewerRoleAdmin,
Expand Down
1 change: 0 additions & 1 deletion hypha/apply/projects/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,4 @@ class ManageAdminGoup(ModelAdminGroup):
menu_icon = 'folder-open-inverse'
items = (
DocumentCategoryAdmin,
ProjectApprovalFormAdmin,
)
8 changes: 4 additions & 4 deletions hypha/apply/projects/forms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
)
from .project import (
ApproveContractForm,
CreateApprovalForm,
ChangePAFStatusForm,
CreateProjectForm,
FinalApprovalForm,
ProjectApprovalForm,
RejectionForm,
RemoveDocumentForm,
SetPendingForm,
StaffUploadContractForm,
Expand All @@ -30,10 +30,10 @@
__all__ = [
'SelectDocumentForm',
'ApproveContractForm',
'ChangePAFStatusForm',
'CreateProjectForm',
'CreateApprovalForm',
'FinalApprovalForm',
'ProjectApprovalForm',
'RejectionForm',
'RemoveDocumentForm',
'SetPendingForm',
'UploadContractForm',
Expand Down
56 changes: 28 additions & 28 deletions hypha/apply/projects/forms/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@
from hypha.apply.stream_forms.forms import StreamBaseForm
from hypha.apply.users.groups import STAFF_GROUP_NAME

from ..models.project import COMMITTED, Approval, Contract, PacketFile, Project
from ..models.project import (
COMMITTED,
PAF_STATUS_CHOICES,
Contract,
PacketFile,
PAFReviewersRole,
Project,
)

User = get_user_model()

Expand Down Expand Up @@ -56,25 +63,17 @@ def save(self, *args, **kwargs):
return Project.create_from_submission(submission)


class CreateApprovalForm(forms.ModelForm):
by = forms.ModelChoiceField(
queryset=User.objects.approvers(),
widget=forms.HiddenInput(),
)
class FinalApprovalForm(forms.ModelForm):
name_prefix = 'final_approval_form'
final_approval_status = forms.ChoiceField(choices=PAF_STATUS_CHOICES)
comment = forms.CharField(required=False, widget=forms.Textarea)

class Meta:
model = Approval
fields = ('by',)

def __init__(self, user=None, *args, **kwargs):
self.user = user
super().__init__(*args, **kwargs)
model = Project
fields = ['final_approval_status', 'comment']

def clean_by(self):
by = self.cleaned_data['by']
if by != self.user:
raise forms.ValidationError(_('Cannot approve for a different user'))
return by
def __init__(self, instance, user=None, *args, **kwargs):
super().__init__(instance=instance, *args, **kwargs)


class MixedMetaClass(type(StreamBaseForm), type(forms.ModelForm)):
Expand Down Expand Up @@ -113,11 +112,19 @@ def save(self, *args, **kwargs):
return super().save(*args, **kwargs)


class RejectionForm(forms.Form):
comment = forms.CharField(widget=forms.Textarea)
class ChangePAFStatusForm(forms.ModelForm):
name_prefix = 'change_paf_status_form'
paf_reviewers_roles = PAFReviewersRole.objects.all().only('role')
paf_status = forms.ChoiceField(choices=PAF_STATUS_CHOICES)
role = forms.ModelChoiceField(queryset=paf_reviewers_roles)
comment = forms.CharField(required=False, widget=forms.Textarea)

def __init__(self, instance=None, user=None, *args, **kwargs):
super().__init__(*args, **kwargs)
class Meta:
fields = ['paf_status', 'role', 'comment']
model = Project

def __init__(self, instance, user, *args, **kwargs):
super().__init__(instance=instance, *args, **kwargs)


class RemoveDocumentForm(forms.ModelForm):
Expand All @@ -144,15 +151,8 @@ def clean(self):
if self.instance.status != COMMITTED:
raise forms.ValidationError(_('A Project can only be sent for Approval when Committed.'))

if self.instance.is_locked:
raise forms.ValidationError(_('A Project can only be sent for Approval once'))

super().clean()

def save(self, *args, **kwargs):
self.instance.is_locked = True
return super().save(*args, **kwargs)


class UploadContractForm(forms.ModelForm):
class Meta:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 3.2.14 on 2022-08-09 04:59

from django.db import migrations, models
import django.db.models.deletion
import modelcluster.fields


class Migration(migrations.Migration):

dependencies = [
('application_projects', '0054_alter_project_form_fields'),
]

operations = [
migrations.AddField(
model_name='project',
name='paf_reviews_meta_data',
field=models.JSONField(default=dict, help_text='Reviewers role and their actions/comments'),
),
migrations.AlterField(
model_name='project',
name='status',
field=models.TextField(choices=[('committed', 'Committed'), ('waiting_for_approval', 'Waiting for Approval'), ('contracting', 'Contracting'), ('in_progress', 'In Progress'), ('closing', 'Closing'), ('complete', 'Complete')], default='committed'),
),
migrations.CreateModel(
name='PAFReviewersRole',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
('role', models.CharField(max_length=200)),
('page', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='paf_reviewers_roles', to='application_projects.projectsettings')),
],
options={
'ordering': ['sort_order'],
'abstract': False,
},
),
]
Loading