Skip to content

Commit

Permalink
Merge pull request #292 from CityOfNewYork/hotfix/OP-1343
Browse files Browse the repository at this point in the history
Hotfix/OP-1343: Denial Reason - Reasons Below
  • Loading branch information
johnyu95 authored Jan 9, 2018
2 parents 5e82434 + cf8f12c commit cc9a5f1
Show file tree
Hide file tree
Showing 11 changed files with 242 additions and 154 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# NYC OpenRecords

NYC OpenRecords is an application that assists individuals in the process of submitting Freedom of Information Law (FOIL) requests to a NCY Agency. The web application also allows government employees to manage, respond to, and fulfill incoming requests.
NYC OpenRecords is an application that assists individuals in the process of submitting Freedom of Information Law (FOIL) requests to a NYC Agency. The web application also allows government employees to manage, respond to, and fulfill incoming requests.

# Technical Details
NYC OpenRecords is a Python web application built using the Flask framework for the backend. The frontend is built using the Bootstrap framework. OpenRecords is compatible with most modern browsers, including Internet Explorer 11 and above.
Expand Down
40 changes: 30 additions & 10 deletions app/response/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
request as flask_request,
render_template,
url_for,
jsonify
jsonify,
Markup
)
from app import email_redis, calendar
from app.constants import (
Expand Down Expand Up @@ -247,15 +248,15 @@ def add_closing(request_id, reason_ids, email_content):
"""
current_request = Requests.query.filter_by(id=request_id).one()
if current_request.status != request_status.CLOSED and (
current_request.was_acknowledged or current_request.was_reopened):
current_request.was_acknowledged or current_request.was_reopened):
if current_request.privacy['agency_request_summary'] or not current_request.agency_request_summary:
reason = "Agency Request Summary must be public and not empty, "
if current_request.responses.filter(
Responses.type != response_type.NOTE, # ignore Notes
Responses.type != response_type.EMAIL, # ignore Emails
Responses.deleted == False, # ignore deleted responses
Responses.privacy != RELEASE_AND_PUBLIC, # ignore public responses
Responses.is_editable == True # ignore non-editable responses
Responses.type != response_type.NOTE, # ignore Notes
Responses.type != response_type.EMAIL, # ignore Emails
Responses.deleted == False, # ignore deleted responses
Responses.privacy != RELEASE_AND_PUBLIC, # ignore public responses
Responses.is_editable == True # ignore non-editable responses
).first() is not None:
raise UserRequestException(action="close",
request_id=current_request.id,
Expand Down Expand Up @@ -640,8 +641,27 @@ def _denial_email_handler(request_id, data, page, agency_name, email_template):
:return: the HTML of the rendered template of a closing
"""
reasons = [Reasons.query.filter_by(id=reason_id).one().content
for reason_id in data.getlist('reason_ids[]')]
_reasons = [Reasons.query.with_entities(Reasons.title, Reasons.content).filter_by(id=reason_id).one()
for reason_id in data.getlist('reason_ids[]')]

# Determine if a custom reason is used
# TODO: Hardcoded values; Need to figure out a better way to do this; Might be part of Agency Features at a later date.
custom_reasons = any('Denied - Reason Below' in x[0] for x in _reasons)

# In order to handle the custom logic for an empty denial reason, remove the reason from the list and pass in
# "custom_reasons" to the template so that the code is generated correctly.
if custom_reasons:
for reason in _reasons:
if reason[0] == 'Denied - Reason Below':
_reasons.remove(reason)
break

reasons = render_template(
os.path.join(current_app.config['EMAIL_TEMPLATE_DIR'], '_email_response_determinations_list.html'),
reasons=_reasons,
custom_reasons=custom_reasons
)

header = CONFIRMATION_HEADER_TO_REQUESTER
req = Requests.query.filter_by(id=request_id).one()
if eval_request_bool(data['confirmation']):
Expand All @@ -657,7 +677,7 @@ def _denial_email_handler(request_id, data, page, agency_name, email_template):
request=req,
agency_appeals_email=req.agency.appeals_email,
agency_name=agency_name,
reasons=reasons,
reasons=Markup(reasons),
page=page),
"header": header
}), 200
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<span class="mceNonEditable">
<ul>
{% for reason, text in reasons %}
<li><span class="mceNonEditable">{{ text }}</span></li>
{% endfor %}
</ul>
</span>
{% if custom_reasons %}
<br/><br/>
{% endif %}
138 changes: 94 additions & 44 deletions app/templates/email_templates/email_edit_file.html
Original file line number Diff line number Diff line change
@@ -1,101 +1,151 @@
{% extends 'email_templates/email_response.html' %}
{% block response_content %}
{% if not agency %}
<div class="mceNonEditable">
{% if response_data.data_old['privacy'] != response_privacy.PRIVATE %}
<p>
A FILE in request <a href="{{ page }}">{{ request_id }}</a> has been edited.
<span class="mceNonEditable">
A file in request <a href="{{ page }}">{{ request_id }}</a> has been edited.
</span>
</p>
{% else %}
<p>
A FILE in request <a href="{{ page }}">{{ request_id }}</a> is available for you to view.
<span class="mceNonEditable">
A file in request <a href="{{ page }}">{{ request_id }}</a> is available for you to view.
</span>
</p>
<div class="file-links">
{% if response_data.response.request.requester.is_anonymous_requester %}
<p>
Link to file: <a href="{{ response_data.file_link_for_user['requester'] }}">
{% if response_data.data_new['name'] %}
{{ response_data.data_new['name'] }}
{% else %}
{{ response_data.response.name }}
{% endif %}
</a>
<span class="mceNonEditable">
Link to file: <a href="{{ response_data.file_link_for_user['requester'] }}">
{% if response_data.data_new['name'] %}
{{ response_data.data_new['name'] }}
{% else %}
{{ response_data.response.name }}
{% endif %}
</a>
</span>
</p>
</div>
{% endif %}
{% endif %}
</div>
{% endif %}

{% if response_data is not none %}
{% if agency or response_data.data_old['privacy'] != response_privacy.PRIVATE %}
<div class="mceNonEditable">
{% if response_data.data_old['hash'] %}
{% if response_data.data_old['name'] %}
<p>
The <strong>file</strong>:
<span class="mceNonEditable">
The <strong>file</strong>:
</span>
</p>
<p style="padding-left: 30px;">
<span class="mceNonEditable">
{{ response_data.data_old['name'] }}
</span>
</p>
<p><span class="mceNonEditable"> has been replaced with: </span></p>
<p style="padding-left: 30px;">
<span class="mceNonEditable">
{{ response_data.data_new['name'] }}
</span>
</p>
<p style="padding-left: 30px;">{{ response_data.data_old['name'] }}</p>
<p> has been replaced with: </p>
<p style="padding-left: 30px;">{{ response_data.data_new['name'] }}</p>
{% else %}
<p>The <strong>contents</strong> of {{ response_data.response.name }} have been changed.</p>
<p>
<span class="mceNonEditable">
The <strong>contents</strong> of {{ response_data.response.name }} have been changed.
</span>
</p>
{% endif %}
{% else %} <!-- If the file has only been renamed -->
{% if response_data.data_old['name'] %}
<p>
The file's <strong>name</strong> was changed from:
<span class="mceNonEditable">
The file's <strong>name</strong> was changed from:
</span>
</p>
<p style="padding-left: 30px;">
<span class="mceNonEditable">
{{ response_data.data_old['name'] }}
</span>
</p>
<p><span class="mceNonEditable"> to: </span></p>
<p style="padding-left: 30px;">
<span class="mceNonEditable">
{{ response_data.data_new['name'] }}
</span>
</p>
<p style="padding-left: 30px;">{{ response_data.data_old['name'] }}</p>
<p> to: </p>
<p style="padding-left: 30px;">{{ response_data.data_new['name'] }}</p>
{% endif %}
{% endif %}

{% if response_data.data_old['title'] %}
<p>
The <strong>title</strong> was changed from :
<span class="mceNonEditable">
The <strong>title</strong> was changed from :
</span>
</p>
<p style="padding-left: 30px;">
<span class="mceNonEditable">
{{ response_data.data_old['title'] }}
</span>
</p>
<p><span class="mceNonEditable"> to: </span></p>
<p style="padding-left: 30px;">
<span class="mceNonEditable">
{{ response_data.data_new['title'] }}
</span>
</p>
<p style="padding-left: 30px;">{{ response_data.data_old['title'] }}</p>
<p> to: </p>
<p style="padding-left: 30px;">{{ response_data.data_new['title'] }}</p>
{% endif %}

{% if agency and response_data.data_old['privacy'] %}
<p>
The <strong>privacy</strong> was changed from :
<span class="mceNonEditable">
The <strong>privacy</strong> was changed from :
</span>
</p>
<p style="padding-left: 30px;">
<span class="mceNonEditable">
{{ response_data.data_old['privacy'] | format_response_privacy }}
</span>
</p>
<p><span class="mceNonEditable"> to: </span></p>
<p style="padding-left: 30px;">
<span class="mceNonEditable">
{{ response_data.data_new['privacy'] | format_response_privacy }}
</span>
</p>
<p style="padding-left: 30px;">{{ response_data.data_old['privacy'] | format_response_privacy }}</p>
<p> to: </p>
<p style="padding-left: 30px;">{{ response_data.data_new['privacy'] | format_response_privacy }}</p>
{% endif %}

<div class="file-links">
{% if not agency and response_data.response.request.requester.is_anonymous_requester %}
<p>
Link to file: <a href="{{ response_data.file_link_for_user['requester'] }}">
{% if response_data.data_new['name'] %}
{{ response_data.data_new['name'] }}
{% else %}
{{ response_data.response.name }}
{% endif %}
</a>
<span class="mceNonEditable">
Link to file: <a href="{{ response_data.file_link_for_user['requester'] }}">
{% if response_data.data_new['name'] %}
{{ response_data.data_new['name'] }}
{% else %}
{{ response_data.response.name }}
{% endif %}
</a>
</span>
</p>
{% endif %}

{% if agency or not response_data.response.request.requester.is_anonymous_requester %}
<p>
Link to file: <a href="{{ response_data.file_link_for_user['agency'] }}">
{% if response_data.data_new['name'] %}
{{ response_data.data_new['name'] }}
{% else %}
{{ response_data.response.name }}
{% endif %}
</a>
<span class="mceNonEditable">
Link to file: <a href="{{ response_data.file_link_for_user['agency'] }}">
{% if response_data.data_new['name'] %}
{{ response_data.data_new['name'] }}
{% else %}
{{ response_data.response.name }}
{% endif %}
</a>
</span>
</p>
{% endif %}
</div>
</div>
{% endif %}
{% endif %}
<p>
Expand Down
32 changes: 20 additions & 12 deletions app/templates/email_templates/email_edit_private_response.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,27 @@
</p>

{% for key, value in response_data.data_old.items() %}
<div class="mceNonEditable">
<p>
<p>
<span class="mceNonEditable">
The <strong>{{ key }}</strong> was changed from:
</span>
</p>
{% if key == 'privacy' %}
<p style="padding-left: 30px;">
<span class="mceNonEditable"> {{ response_data.data_old[key] | format_response_privacy }} </span>
</p>
{% if key == 'privacy' %}
<p style="padding-left: 30px;"> {{ response_data.data_old[key] | format_response_privacy }} </p>
<p> to: </p>
<p style="padding-left: 30px;"> {{ response_data.data_new[key] | format_response_privacy }} </p>
{% else %}
<p style="padding-left: 30px;"> {{ response_data.data_old[key] }} </p>
<p> to: </p>
<p style="padding-left: 30px;"> {{ response_data.data_new[key] }} </p>
{% endif %}
</div>
<p><span class="mceNonEditable"> to: </span></p>
<p style="padding-left: 30px;">
<span class="mceNonEditable"> {{ response_data.data_new[key] | format_response_privacy }} </span>
</p>
{% else %}
<p style="padding-left: 30px;">
<span class="mceNonEditable"> {{ response_data.data_old[key] }} </span>
</p>
<p><span class="mceNonEditable"> to: </span></p>
<p style="padding-left: 30px;">
<span class="mceNonEditable"> {{ response_data.data_new[key] }} </span>
</p>
{% endif %}
<p><br /></p>
{% endfor %}
18 changes: 9 additions & 9 deletions app/templates/email_templates/email_edit_response.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@

{% if response_data is not none %}
{% if response_data.data_old['privacy'] != response_privacy.PRIVATE and not agency %}
<div class="mceNonEditable">
{% for key in response_data.requester_viewable_keys %}
<p>
{% for key in response_data.requester_viewable_keys %}
<p>
<span class="mceNonEditable">
The <strong>{{ key }}</strong> was changed from:
</p>
<p style="padding-left: 30px;"> {{ response_data.data_old[key] }} </p>
<p> to: </p>
<p style="padding-left: 30px;"> {{ response_data.data_new[key] }} </p>
{% endfor %}
</div>
</span>
</p>
<p style="padding-left: 30px;"><span class="mceNonEditable"> {{ response_data.data_old[key] }} </span></p>
<p><span class="mceNonEditable"> to: <span class="mceNonEditable"></p>
<p style="padding-left: 30px;"><span class="mceNonEditable"> {{ response_data.data_new[key] }} </span></p>
{% endfor %}
{% endif %}
{% if agency %}
{% for key, value in response_data.data_old.items() %}
Expand Down
24 changes: 12 additions & 12 deletions app/templates/email_templates/email_private_file_upload.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
<p>
Attention {{ agency_name }} Users,
</p>
<div class="mceNonEditable">
<p>
<p>
<span class="mceNonEditable">
The following file(s) were added to <a href='{{ page }}'>{{ request_id }}</a> and are private:
</p>
<div class="file-links">
<ul>
{% for file in private_links %}
<li style="list-style: none">
{{ file['title'] }}: <a href="{{ file['link'] }}">{{ file['filename'] }}</a>
</li>
{% endfor %}
</ul>
</div>
</span>
</p>
<div class="file-links">
<ul>
{% for file in private_links %}
<li style="list-style: none">
<span class="mceNonEditable">{{ file['title'] }}: <a href="{{ file['link'] }}">{{ file['filename'] }}</a></span>
</li>
{% endfor %}
</ul>
</div>
<p><br></p>
{% else %}
Expand Down
Loading

0 comments on commit cc9a5f1

Please sign in to comment.