Skip to content

Commit

Permalink
notification: create 'at_desk' notification
Browse files Browse the repository at this point in the history
When an item arrives 'at_desk' a notification was already sent to the
patron to alert it that the item is now available (availability
notification). A sibling notification is now sent to the transaction
library (at_desk notification) ; mainly for printing usage.

Closes #2695.

Co-Authored-by: Renaud Michotte <renaud.michotte@gmail.com>
  • Loading branch information
zannkukai committed Apr 21, 2022
1 parent b7b9a62 commit 32641e2
Show file tree
Hide file tree
Showing 15 changed files with 259 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
}
}
},
"availability_notification_setting": {
"delayed_notification_setting": {
"additionalProperties": false,
"required": [
"type",
Expand All @@ -51,7 +51,10 @@
"properties": {
"type": {
"type": "string",
"const": "availability"
"enum": [
"at_desk",
"availability"
]
},
"email": {
"title": "E-mail",
Expand Down Expand Up @@ -367,7 +370,7 @@
"$ref": "#/definitions/default_notification_setting"
},
{
"$ref": "#/definitions/availability_notification_setting"
"$ref": "#/definitions/delayed_notification_setting"
}
]
}
Expand Down
12 changes: 8 additions & 4 deletions rero_ils/modules/loans/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -800,10 +800,12 @@ def get_notification_candidates(self, trigger):
requests = [loan_pid for loan_pid in requests if loan_pid != self.pid]
has_request = len(requests) > 0

# AVAILABILITY NOTIFICATION
# AVAILABILITY & AT_DESK NOTIFICATION
# If loan (items) just arrived at the library desk we can create
# an AVAILABILITY notification
# an AVAILABILITY and AT_DESK notifications. AVAILABILITY is sent to
# the patron, AT_DESK is sent to transaction library.
if self.state == LoanState.ITEM_AT_DESK:
candidates.append((self, NotificationType.AT_DESK))
candidates.append((self, NotificationType.AVAILABILITY))

# REQUEST & RECALL NOTIFICATION
Expand Down Expand Up @@ -857,8 +859,10 @@ def create_notification(self, trigger=None, _type=None, counter=0):
create = True # Should the notification actually be created.
# Internal notification (library destination) should be directly
# dispatched. Other notifications types could be asynchronously
# processed (to save server response time).
dispatch = n_type in NotificationType.INTERNAL_NOTIFICATIONS
# processed (to save server response time) except for AT_DESK
# notification where a delay could be configured
dispatch = n_type in NotificationType.INTERNAL_NOTIFICATIONS \
and n_type != NotificationType.AT_DESK

record = {
'creation_date': datetime.now(timezone.utc).isoformat(),
Expand Down
2 changes: 2 additions & 0 deletions rero_ils/modules/notifications/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def _get_circulation_subclass(record):
"""Get the Notification subclass to use based on record data."""
from .api import Notification
from .subclasses.acq_order import AcquisitionOrderNotification
from .subclasses.at_desk import AtDeskCirculationNotification
from .subclasses.availability import \
AvailabilityCirculationNotification
from .subclasses.booking import BookingCirculationNotification
Expand All @@ -45,6 +46,7 @@ def _get_circulation_subclass(record):
from .subclasses.transit import TransitCirculationNotification
mapping = {
NotificationType.AVAILABILITY: AvailabilityCirculationNotification,
NotificationType.AT_DESK: AtDeskCirculationNotification,
NotificationType.BOOKING: BookingCirculationNotification,
NotificationType.DUE_SOON: ReminderCirculationNotification,
NotificationType.OVERDUE: ReminderCirculationNotification,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
"due_soon",
"overdue",
"availability",
"at_desk",
"recall",
"transit_notice",
"request",
Expand Down
26 changes: 16 additions & 10 deletions rero_ils/modules/notifications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,18 @@ class NotificationMetadata(db.Model, RecordMetadataBase):
class NotificationType:
"""Types of notifications.
- RECALL : when a new request is done on a loaned item.
- AVAILABILITY : when a requested item arrives at desk.
- REQUEST : created when the item is at desk and a request occurs.
Note: can have a delay.
- BOOKING : when the item is checked in and have a request.
- TRANSIT_NOTICE : when an item is sent to the owning location/library
- DUE_SOON : when the loaned item is about to expire.
- OVERDUE : when the loaned item is expired.
- ACQUISITION_ORDER
: when an acquisition order is send to a vendor.
- RECALL : when a new request is done on a loaned item.
- AT_DESK : when a requested item arrives at desk ; sent to the
transaction library. (possible configurable delay)
- AVAILABILITY : when a requested item arrives at desk sent to the
patron. (possible configurable delay)
- REQUEST : created when the item is at desk and a request
occurs.
- BOOKING : when the item is checked in and have a request.
- TRANSIT_NOTICE : when an item is sent to the owning location/library
- DUE_SOON : when the loaned item is about to expire.
- OVERDUE : when the loaned item is expired.
- ACQUISITION_ORDER : when an acquisition order is send to a vendor.
"""

RECALL = 'recall'
Expand All @@ -65,9 +67,11 @@ class NotificationType:
REQUEST = 'request'
BOOKING = 'booking'
ACQUISITION_ORDER = 'acquisition_order'
AT_DESK = 'at_desk'

# All notification types
ALL_NOTIFICATIONS = [
AT_DESK,
AVAILABILITY,
DUE_SOON,
OVERDUE,
Expand All @@ -83,13 +87,15 @@ class NotificationType:
]
# Notification to send to a library (not to a patron)
INTERNAL_NOTIFICATIONS = [
AT_DESK,
BOOKING,
REQUEST,
TRANSIT_NOTICE
]

# Notification related to circulation modules
CIRCULATION_NOTIFICATIONS = [
AT_DESK,
AVAILABILITY,
DUE_SOON,
OVERDUE,
Expand Down
104 changes: 104 additions & 0 deletions rero_ils/modules/notifications/subclasses/at_desk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
#
# RERO ILS
# Copyright (C) 2022 RERO
# Copyright (C) 2022 UCLouvain
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""API for manipulating "at_desk" circulation notifications."""

from __future__ import absolute_import, print_function

from rero_ils.filter import format_date_filter
from rero_ils.modules.documents.dumpers import DocumentGenericDumper
from rero_ils.utils import language_iso639_2to1

from .internal import InternalCirculationNotification
from ...items.dumpers import ItemNotificationDumper
from ...locations.api import Location
from ...patrons.api import Patron
from ...patrons.dumpers import PatronNotificationDumper


class AtDeskCirculationNotification(InternalCirculationNotification):
"""At_desk circulation notifications class.
An "at_desk" notification is a message send to a library to notify that an
item arrives AT_DESK. It's just the same than AVAILABILITY notification
except that the notification isn't send to the patron but to the
transaction library.
Administrator can define a delay between notification creation and
notification dispatching.
As one of the purpose of this notification is to be printed, it should
never be aggregated.
"""

def get_template_path(self):
"""Get the template to use to render the notification."""
return f'email/at_desk/{self.get_language_to_use()}.txt'

def get_recipients_to(self):
"""Get notification recipient email addresses."""
# At desk notification will be sent to the loan transaction library.
recipient = self.transaction_library.get_email(self.type)
if recipient:
return [recipient]

@classmethod
def get_notification_context(cls, notifications=None):
"""Get the context to render the notification template."""
context = {'loans': []}
notifications = notifications or []

doc_dumper = DocumentGenericDumper()
item_dumper = ItemNotificationDumper()
patron_dumper = PatronNotificationDumper()
for notification in notifications:
loan = notification.loan
creation_date = format_date_filter(
notification.get('creation_date'), date_format='medium',
locale=language_iso639_2to1(notification.get_language_to_use())
)
request_expire_date = format_date_filter(
loan.get('request_expire_date'), date_format='medium',
locale=language_iso639_2to1(notification.get_language_to_use())
)
# merge doc and item metadata preserving document key
item_data = notification.item.dumps(dumper=item_dumper)
doc_data = notification.document.dumps(dumper=doc_dumper)
doc_data = {**item_data, **doc_data}
# pickup location name --> !! pickup is on notif.request_loan, not
# on notif.loan
request_loan = notification.request_loan
pickup_location = Location.get_record_by_pid(
request_loan.get('pickup_location_pid'))
if not pickup_location:
pickup_location = Location.get_record_by_pid(
request_loan.get('transaction_location_pid'))
# request_patron
request_patron = Patron.get_record_by_pid(
request_loan.get('patron_pid'))

loan_context = {
'creation_date': creation_date,
'document': doc_data,
'pickup_name': pickup_location.get(
'pickup_name', pickup_location.get('name')),
'request_expire_date': request_expire_date,
'patron': request_patron.dumps(dumper=patron_dumper)
}
context['loans'].append(loan_context)

return context
17 changes: 17 additions & 0 deletions rero_ils/modules/notifications/templates/email/at_desk/eng.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Item at desk

{% for loan in loans -%}
Date: {{ loan.creation_date }}
Title: {{ loan.document.title_text }}
Barcode: {{ loan.document.barcode }}
Location: {{ loan.document.library_name }} / {{ loan.document.location_name }}
{%- if loan.document.call_numbers %}
Call number: {{ loan.document.call_numbers | join(' | ') }}
{%- endif %}

Pick up location: {{ loan.pickup_name }}
Patron: {{ loan.patron.first_name }} {{ loan.patron.last_name }}
{%- if loan.patron.barcode %} - {{ loan.patron.barcode | join(', ') }}{%- endif %}
Request expiration: {{ loan.request_expire_date }}

{% endfor %}
17 changes: 17 additions & 0 deletions rero_ils/modules/notifications/templates/email/at_desk/fre.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Exemplaire au bureau de prêt

{% for loan in loans -%}
Date: {{ loan.creation_date }}
Titre: {{ loan.document.title_text }}
Code-barres: {{ loan.document.barcode }}
Localisation: {{ loan.document.library_name }} / {{ loan.document.location_name }}
{%- if loan.document.call_numbers %}
Cote: {{ loan.document.call_numbers | join(' | ') }}
{%- endif %}

Lieu de retrait: {{ loan.pickup_name }}
Lecteur: {{ loan.patron.first_name }} {{ loan.patron.last_name }}
{%- if loan.patron.barcode %} - {{ loan.patron.barcode | join(', ') }}{%- endif %}
Expiration de la demande: {{ loan.request_expire_date }}

{% endfor %}
17 changes: 17 additions & 0 deletions rero_ils/modules/notifications/templates/email/at_desk/ger.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Exemplar an der Ausleihtheke

{% for loan in loans %}
Datum: {{ loan.creation_date }}
Titel: {{ loan.document.title_text }}
Strichcode: {{ loan.document.barcode }}
Standort: {{ loan.document.library_name }} / {{ loan.document.location_name }}
{%- if loan.document.call_numbers %}
Signatur: {{ loan.document.call_numbers | join(' | ') }}
{%- endif %}

Abholort: {{ loan.pickup_name }}
Leser: {{ loan.patron.first_name }} {{ loan.patron.last_name }}
{%- if loan.patron.barcode %} - {{ loan.patron.barcode | join(', ') }}{%- endif %}
Ablauf der bestellung: {{ loan.request_expire_date }}

{% endfor %}
18 changes: 18 additions & 0 deletions rero_ils/modules/notifications/templates/email/at_desk/ita.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Esemplare al banco prestiti

{% for loan in loans %}
Data: {{ loan.creation_date }}
Titolo: {{ loan.document.title_text }}
Codice a barre: {{ loan.document.barcode }}
Localizzazione: {{ loan.document.library_name }} / {{ loan.document.location_name }}
{%- if loan.document.call_numbers %}
Segnatura: {{ loan.document.call_numbers | join(' | ') }}
{%- endif %}

Punto di ritiro: {{ loan.pickup_name }}
Lettore: {{ loan.patron.first_name }} {{ loan.patron.last_name }}
{%- if loan.patron.barcode %} - {{ loan.patron.barcode | join(', ') }}{%- endif %}
Scadenza della richiesta: {{ loan.request_expire_date }}


{% endfor %}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Réservation{%- if loans[0].in_transit %} (avec transit){%- endif %}
{% for loan in loans -%}
Date: {{ loan.creation_date }}
Titre: {{ loan.document.title_text }}
Code-barre: {{ loan.document.barcode }}
Code-barres: {{ loan.document.barcode }}
Localisation: {{ loan.document.library_name }} / {{ loan.document.location_name }}
{%- if loan.document.call_numbers %}
Cote: {{ loan.document.call_numbers | join(' | ') }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Demande{%- if loans[0].in_transit %} (avec transit){%- endif %}
{% for loan in loans -%}
Date: {{ loan.creation_date }}
Titre: {{ loan.document.title_text }}
Code-barre: {{ loan.document.barcode }}
Code-barres: {{ loan.document.barcode }}
Localisation: {{ loan.document.library_name }} / {{ loan.document.location_name }}
{%- if loan.document.call_numbers %}
Cote: {{ loan.document.call_numbers | join(' | ') }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Avis de transit
{% for loan in loans %}
Date: {{ loan.creation_date }}
Titre: {{ loan.document.title_text }}
Code-barre: {{ loan.document.barcode }}
Code-barres: {{ loan.document.barcode }}
{%- if loan.document.call_numbers %}
Cote: {{ loan.document.call_numbers | join(' | ') }}
{%- endif %}
Expand Down
Loading

0 comments on commit 32641e2

Please sign in to comment.