Skip to content

Commit

Permalink
Adds option to reject credential applications based on template
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas-Mc committed Feb 12, 2021
1 parent efa4fcb commit 0fc5efe
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 15 deletions.
27 changes: 27 additions & 0 deletions physionet-django/console/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,26 @@
(None, 'N/A or Undetermined')
)

REJECT_REASONS = (
(15, 'Inconsistent information'),
(14, 'Incorrect CITI course / wrong PDF'),
(13, 'CITI Certificate'),
(12, 'No HIPAA section'),
(11, 'Failed HIPAA section'),
(10, 'Inconsistent CITI report email'),
(9, 'Industry Researcher without institution'),
(8, 'Hospital Researcher without institution'),
(7, 'Student without institution'),
(6, 'MIT Affiliates as institution'),
(5, 'Incorrect reference name'),
(4, 'Listed self as reference'),
(3, 'Inactive reference email'),
(2, 'Can not verify identity'),
(1, 'DUA violation'),
(0, 'Other'),
)


class AssignEditorForm(forms.Form):
"""
Assign an editor to a project under submission
Expand Down Expand Up @@ -341,6 +361,13 @@ class ContactCredentialRefForm(forms.Form):
body = forms.CharField(widget=forms.Textarea)


class CredentialRejectForm(forms.Form):
"""
Decide the reason for rejecting a credentialing application.
"""
reason = forms.ChoiceField(choices=REJECT_REASONS)


class ProcessCredentialForm(forms.ModelForm):
"""
Form to respond to a credential application
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,30 @@ <h2 style='font-size:20px;'>Reference comments:</h2>
</div>
</div>
{% endif %}
<div class="card mb-4">
<div class="card-header">
Reject with a template.
</div>
<div class="card-body">
<form action="" method="post" class="form-signin">
{% csrf_token %}
{% include "form_snippet.html" with form=reject_credential_form %}
<button class="btn btn-primary btn-lg" name="reject_template" value="{{app_user.id}}" type="submit">Reject</button>
</form>
</div>
</div>
{% if modal_id == "reject-template-modal" %}
{% include "console/email_modal.html" with form=form app_user=app_user modal_id=modal_id modal_title=modal_title submit_name=submit_name submit_value=submit_value submit_text=submit_text %}
{% endif %}
</div>
</div>
</div>

{% if modal_id == "reject-template-modal" %}
<script>
$(document).ready(function(){
$("#{{modal_id}}").modal('show');
});
</script>
{% endif %}
{% endblock %}
42 changes: 41 additions & 1 deletion physionet-django/console/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,7 @@ def process_credential_application(request, application_slug):

process_credential_form = forms.ProcessCredentialReviewForm(responder=request.user,
instance=application)
reject_credential_form = forms.CredentialRejectForm()

ref_email = notification.contact_reference(request, application,
send=False, wordwrap=False)
Expand Down Expand Up @@ -1327,6 +1328,30 @@ def process_credential_application(request, application_slug):
responder=request.user, instance=application)
else:
messages.error(request, 'Invalid review. See form below.')
elif 'reject_template' in request.POST:
cred_reject_form = forms.CredentialRejectForm(
data=request.POST)
if cred_reject_form.is_valid():
template_choice = int(cred_reject_form.cleaned_data['reason'])
reject_email = notification.process_credential_complete(
request, application, send=False, response_choice=template_choice)
form = forms.ContactCredentialRefForm(initial=reject_email)
app_user = application.user
modal_id = 'reject-template-modal'
modal_title = 'Reject with a template'
submit_name = 'reject_applicant'
submit_value = application.user.id
submit_text = 'Reject with a template'
return render(request, 'console/process_credential_application.html',
{'application': application, 'app_user': application.user,
'intermediate_credential_form': intermediate_credential_form,
'process_credential_form': process_credential_form,
'processing_credentials_nav': True, 'page_title': page_title,
'contact_cred_ref_form': contact_cred_ref_form,
'reject_credential_form': reject_credential_form,
'form':form, 'app_user':app_user, 'modal_id':modal_id,
'modal_title':modal_title, 'submit_name':submit_name,
'submit_value':submit_value, 'submit_text':submit_text})
elif 'approve_response_all' in request.POST:
if request.POST['decision'] == '0':
messages.error(request, 'You selected Reject. Did you mean to Approve All?')
Expand All @@ -1344,6 +1369,20 @@ def process_credential_application(request, application_slug):
page_title = title_dict[application.credential_review.status]
intermediate_credential_form = forms.ProcessCredentialReviewForm(
responder=request.user, instance=application)
elif 'reject_applicant' in request.POST:
contact_cred_ref_form = forms.ContactCredentialRefForm(
data=request.POST)
if contact_cred_ref_form.is_valid():
application.status = 1
application.responder = request.user
application.reject(application.responder)
application.save()
subject = contact_cred_ref_form.cleaned_data['subject']
body = contact_cred_ref_form.cleaned_data['body']
notification.process_credential_complete(request, application,
subject=subject, body=body)
return render(request, 'console/process_credential_complete.html',
{'application':application})
elif 'contact_reference' in request.POST:
contact_cred_ref_form = forms.ContactCredentialRefForm(
data=request.POST)
Expand Down Expand Up @@ -1374,7 +1413,8 @@ def process_credential_application(request, application_slug):
'process_credential_form': process_credential_form,
'processing_credentials_nav': True, 'page_title': page_title,
'contact_cred_ref_form': contact_cred_ref_form,
'known_active': known_active, 'known_cred': known_cred})
'known_active': known_active, 'known_cred': known_cred,
'reject_credential_form': reject_credential_form})


@login_required
Expand Down
62 changes: 48 additions & 14 deletions physionet-django/notification/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,24 @@
from project.models import DataAccessRequest, License

RESPONSE_ACTIONS = {0:'rejected', 1:'accepted'}

RESPONSE_COMMENTS = {
15: 'Some of the information on your application does not make sense. Please resubmit with the correct information.',
14: 'It looks like you did not complete the correct CITI course. The correct course is "Data or Specimens Only Research". Please resubmit with the correct information.',
13: 'You submitted the CITI Certificate instead of the Completion Report (it should include a list of courses and scores). Please resubmit with the correct report.',
12: 'The HIPAA module is missing from your CITI completion report.',
11: 'Please retake the CITI course paying particular attention to the section on HIPAA Privacy Protections.',
10: 'The email on your CITI report does not match your application email. You can not share CITI training reports.',
9: 'You list your research category as Industry Researcher but did not list an institution. Please update your institution or if you are not associated with an institution or select Independent Researcher as your research category.',
8: 'You listed yourself as a Hospital Researcher but did not list an institution. Please resubmit with the correct information.',
7: 'You listed yourself as a Student but did not list an institution. Please resubmit with the correct information.',
6: '"Massachusetts Institute of Technology Affiliates" should not be listed as your institution. This is for the CITI course step only. Please resubmit with the correct information.',
5: 'The name for your reference does not seem correct. Please resubmit with the correct information.',
4: 'You listed yourself as a reference. Please resubmit with another valid reference.',
3: 'The email address listed for your reference is not active (emails sent to this address are undelivered).',
2: 'We cannot identify you or your reference in our web search. Can you resubmit and provide references to your publications, personal webpage, or associations with known organizations?',
1: 'Access is provided to individuals. Your research summary suggests that data may be shared within the group. Please resubmit your application, making it clear that the Data Use Agreement will be followed. If your colleagues plan to access the data, then they will need to apply for access independently.',
0: ''
}

def mailto_url(*recipients, **params):
"""
Expand Down Expand Up @@ -631,23 +648,36 @@ def mailto_administrators(project, error):
send_mail(subject, body, settings.DEFAULT_FROM_EMAIL,
[settings.CONTACT_EMAIL], fail_silently=False)

def process_credential_complete(request, application, comments=True):
def process_credential_complete(request, application, send=True, comments=True,
response_choice=-1, subject='', body=''):
"""
Notify user of credentialing decision
"""
applicant_name = application.get_full_name()
response = 'rejected' if application.status == 1 else 'accepted'
subject = 'Your application for PhysioNet credentialing'
body = loader.render_to_string(
'notification/email/process_credential_complete.html', {
'application': application,
'applicant_name': applicant_name,
'domain': get_current_site(request),
'url_prefix': get_url_prefix(request),
'comments': comments,
'signature': email_signature(),
'footer': email_footer()
})
if not subject:
subject = 'Your application for PhysioNet credentialing'
if (comments == True) and (response_choice >= 0):
response = 'rejected'
application.status = 1
application.responder_comments = RESPONSE_COMMENTS[response_choice]
application.save()

if not body:
body = loader.render_to_string(
'notification/email/process_credential_complete.html', {
'application': application,
'applicant_name': applicant_name,
'domain': get_current_site(request),
'url_prefix': get_url_prefix(request),
'comments': comments,
'signature': email_signature(),
'footer': email_footer()
})

if (comments == True) and (response_choice >= 0) and (not send):
application.status = 0
application.save()

message = EmailMessage(
subject=subject,
Expand All @@ -656,7 +686,11 @@ def process_credential_complete(request, application, comments=True):
to=[application.user.email],
bcc=[settings.CREDENTIAL_EMAIL]
)
message.send(fail_silently=False)

if send:
message.send(fail_silently=False)

return {'subject': subject, 'body': body}

def credential_application_request(request, application):
"""
Expand Down

0 comments on commit 0fc5efe

Please sign in to comment.