Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow documents to be generated from within the registration details #6306

Merged
merged 13 commits into from
Jun 14, 2024
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ Improvements
- Add option to hide person titles throughout the event (:issue:`038`, :pr:`6104`, thanks
:user:`vasantvohra`)
- Preserve input when switching between judgment actions for an editable (:pr:`6375`)
- Allow generating documents from the registration summary page (:issue:`6212`, :pr:`6306`,
thanks :user:`hitenvidhani`)

Bugfixes
^^^^^^^^
Expand Down
5 changes: 5 additions & 0 deletions indico/modules/events/models/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,11 @@ def force_event_locale(self, user=None, *, allow_session=False):
with force_locale(locale):
yield

def has_receipt_templates(self):
"""Check if the event has any receipt document templates."""
from indico.modules.receipts.util import has_any_templates
return has_any_templates(self)


Event.register_location_events()
Event.register_protection_events()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,59 +143,79 @@

{% macro render_receipts_list(registration, from_management=false) %}
{% set receipts = registration.receipt_files if from_management else registration.published_receipts %}
{% if receipts %}
{% set can_generate_receipts = from_management and registration.event.has_receipt_templates() %}

{% if receipts or can_generate_receipts %}
<div class="regform-done">
<div class="i-box-header">
<div class="i-box-title">
{% trans %}Documents{% endtrans %}
</div>
{% if can_generate_receipts %}
<a href="#" class="i-button accept icon-agreement"
data-callback="printReceipts"
data-params="{{ {'registration_id': [registration.id|string],
'event_id': registration.registration_form.event.id,
'reload_after': true} | tojson | forceescape }}">
{% trans %}Generate document{% endtrans %}
</a>
{% endif %}
</div>
<div class="i-box-content">
<table class="registration-info">
{% for receipt in receipts | sort(attribute='file.filename') %}
{% set filename = receipt.file.filename %}
<tr class="{{ 'unpublished-receipt' if not receipt.is_published }}">
<th class="regform-done-caption">{{ receipt.template.type.title if receipt.template.type else '' }}</th>
<td class="regform-done-data">
<a href="{{ url_for('.download_receipt', receipt.locator.filename) if from_management else receipt.registrant_download_url }}">
{{ filename }}
</a>
{% if not receipt.is_published -%}
<span class="unpublished-receipt-warning">({% trans %}not published{% endtrans %})</span>
{% endif %}
</td>
{% if from_management -%}
<td class="actions-column">
<div class="group right entry-action-buttons">
{% if receipt.is_published %}
<a href="#" class="icon-eye-blocked"
title="{% trans %}Unpublish document{% endtrans %}"
data-title="{% trans name=receipt.file.filename %}Unpublish '{{ name }}' to the registrant{% endtrans %}"
data-href="{{ url_for('.unpublish_receipt', receipt) }}"
data-method="POST"
data-update="#receipts-list"
data-confirm="{% trans name=filename %}Are you sure you want to unpublish the document '{{ name }}' to the registrant?{% endtrans %}"></a>
{% else %}
<a href="#" class="icon-eye js-dialog-action"
title="{% trans %}Publish document{% endtrans %}"
data-title="{% trans name=receipt.file.filename %}Publish '{{ name }}' to the registrant{% endtrans %}"
data-href="{{ url_for('.publish_receipt', receipt) }}"
data-update="#receipts-list"
data-ajax-dialog></a>
{% endif %}
<a href="#" class="icon-remove js-delete"
data-title="{% trans name=receipt.file.filename %}Delete the document '{{ name }}'?{% endtrans %}"
title="{% trans %}Delete document{% endtrans %}"
data-confirm="{% trans name=filename %}Are you sure you want to completely delete the document '{{ name }}'?{% endtrans %}"
data-update="#receipts-list"
data-method="DELETE"
data-href="{{ url_for('.delete_receipt', receipt) }}"></a>
</div>
{%- if receipts %}
<table class="registration-info">
{% for receipt in receipts | sort(attribute='file.filename') %}
{% set filename = receipt.file.filename %}
<tr class="{{ 'unpublished-receipt' if not receipt.is_published }}">
<th class="regform-done-caption">{{ receipt.template.type.title if receipt.template.type else '' }}</th>
<td class="regform-done-data">
<a href="{{ url_for('.download_receipt', receipt.locator.filename) if from_management else receipt.registrant_download_url }}">
{{ filename }}
</a>
{% if not receipt.is_published -%}
<span class="unpublished-receipt-warning">({% trans %}not published{% endtrans %})</span>
{% endif %}
</td>
{% endif %}
</tr>
{% endfor %}
</table>
{% if from_management -%}
<td class="actions-column">
<div class="group right entry-action-buttons">
{% if receipt.is_published %}
<a href="#" class="icon-eye-blocked"
title="{% trans %}Unpublish document{% endtrans %}"
data-title="{% trans name=receipt.file.filename %}Unpublish '{{ name }}' to the registrant{% endtrans %}"
data-href="{{ url_for('.unpublish_receipt', receipt) }}"
data-method="POST"
data-update="#receipts-list"
data-confirm="{% trans name=filename %}Are you sure you want to unpublish the document '{{ name }}' to the registrant?{% endtrans %}"></a>
{% else %}
<a href="#" class="icon-eye js-dialog-action"
title="{% trans %}Publish document{% endtrans %}"
data-title="{% trans name=receipt.file.filename %}Publish '{{ name }}' to the registrant{% endtrans %}"
data-href="{{ url_for('.publish_receipt', receipt) }}"
data-update="#receipts-list"
data-ajax-dialog></a>
{% endif %}
<a href="#" class="icon-remove js-delete"
data-title="{% trans name=receipt.file.filename %}Delete the document '{{ name }}'?{% endtrans %}"
title="{% trans %}Delete document{% endtrans %}"
data-confirm="{% trans name=filename %}Are you sure you want to completely delete the document '{{ name }}'?{% endtrans %}"
data-update="#receipts-list"
data-method="DELETE"
data-href="{{ url_for('.delete_receipt', receipt) }}"></a>
</div>
</td>
{% endif %}
</tr>
{% endfor %}
</table>
{%- else -%}
<div class="no-data-placeholder">
<i class="icon-agreement"></i>
<span>
{% trans %}There are no documents yet.{% endtrans %}
</span>
</div>
{%- endif %}
</div>
</div>
{% endif %}
Expand Down
4 changes: 2 additions & 2 deletions indico/modules/receipts/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from indico.core import signals
from indico.modules.events.registration.util import ActionMenuEntry
from indico.modules.receipts.util import can_user_manage_receipt_templates, has_any_receipts, has_any_templates
from indico.modules.receipts.util import can_user_manage_receipt_templates, has_any_receipts
from indico.util.i18n import _
from indico.web.flask.util import url_for
from indico.web.menu import SideMenuItem
Expand Down Expand Up @@ -38,7 +38,7 @@ def _category_sidemenu_items(sender, category, **kwargs):

@signals.event.registrant_list_action_menu.connect
def _get_action_menu_items(regform, **kwargs):
has_templates = has_any_templates(regform.event)
has_templates = regform.event.has_receipt_templates()
if has_templates:
yield ActionMenuEntry(
_('Generate Documents'),
Expand Down
18 changes: 16 additions & 2 deletions indico/modules/receipts/client/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,22 @@ import {injectModal} from 'indico/react/util';

import PrintReceiptsModal from './printing/PrintReceiptsModal';

window.printReceipts = function({registration_id: registrationIds, event_id: eventId}) {
window.printReceipts = function({
registration_id: registrationIds,
event_id: eventId,
reload_after: reloadAfter,
}) {
injectModal(resolve => (
<PrintReceiptsModal onClose={resolve} registrationIds={registrationIds} eventId={eventId} />
<PrintReceiptsModal
onClose={generated => {
if (generated && reloadAfter) {
location.reload();
} else {
resolve();
}
}}
registrationIds={registrationIds}
eventId={eventId}
/>
));
};
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export default function PrintReceiptsModal({onClose, registrationIds, eventId})
filename: 'document',
save_config: true,
}}
onClose={onClose}
onClose={() => onClose(receiptIds.length > 0)}
header={Translate.string('Generate Documents')}
keepDirtyOnReinitialize
noSubmitButton
Expand Down
18 changes: 18 additions & 0 deletions indico/web/client/styles/modules/_registrationform.scss
Original file line number Diff line number Diff line change
Expand Up @@ -641,3 +641,21 @@
max-width: 100%;
max-height: 450px;
}

.no-data-placeholder {
display: flex;
align-items: center;
flex-direction: column;
gap: 15px;
padding: 10px;

i {
font-size: 3em;
color: $dark-gray;
}

span {
font-size: 1.5em;
color: $dark-gray;
}
}
Loading