From a48d0a59d9dadde1798d83373ea446bae72f59ee Mon Sep 17 00:00:00 2001 From: Olivier DOSSMANN Date: Wed, 25 Mar 2020 18:08:45 +0100 Subject: [PATCH] patron: add 'blocked' functionnality * Displays on patron detail view if it is blocked. Displays the blocked reason. * Adds 2 fields on patron detail view: * blocked (if patron is blocked) * blocked reason (why this patron was blocked) * Patron loan detailed view: add a blocked banner if patron is blocked. * Adds different notification to librarian if a patron is blocked while asking for new request Co-Authored-by: Olivier DOSSMANN --- .../checkin/checkin.component.html | 7 +++ .../circulation/patron/loan/loan.component.ts | 28 ++++++++---- .../patron/main/main.component.html | 6 +++ projects/admin/src/app/class/user.ts | 22 +++++++++- .../pipe/patron-blocked-message.pipe.spec.ts | 30 +++++++++++++ .../app/pipe/patron-blocked-message.pipe.ts | 43 +++++++++++++++++++ .../item-request/item-request.component.html | 3 ++ .../patron-detail-view.component.html | 34 ++++++++------- .../patron-detail-view.component.ts | 39 ++++++----------- .../admin/src/app/routes/patrons-route.ts | 9 +++- .../admin/src/app/service/patron.service.ts | 19 -------- .../src/app/shared/shared-pipes.module.ts | 7 ++- projects/admin/src/app/translate/i18n/de.json | 3 ++ projects/admin/src/app/translate/i18n/en.json | 3 ++ .../admin/src/app/translate/i18n/en_US.json | 3 ++ projects/admin/src/app/translate/i18n/es.json | 3 ++ projects/admin/src/app/translate/i18n/fr.json | 3 ++ projects/admin/src/app/translate/i18n/it.json | 3 ++ 18 files changed, 192 insertions(+), 73 deletions(-) create mode 100644 projects/admin/src/app/pipe/patron-blocked-message.pipe.spec.ts create mode 100644 projects/admin/src/app/pipe/patron-blocked-message.pipe.ts diff --git a/projects/admin/src/app/circulation/checkin/checkin.component.html b/projects/admin/src/app/circulation/checkin/checkin.component.html index fd11b7098..b79c96043 100644 --- a/projects/admin/src/app/circulation/checkin/checkin.component.html +++ b/projects/admin/src/app/circulation/checkin/checkin.component.html @@ -30,6 +30,13 @@ + +
+
+ +
+
+
{ let errorMessage = ''; - if (err && err.error && err.error.status) { - errorMessage = err.error.status; + if (err && err.error && err.error.message) { + errorMessage = err.error.message; } if (err.error.status === 403) { - this._toastService.error( - this._translate.instant('Checkout is not allowed by circulation policy'), - this._translate.instant('Checkout') - ); + // Specific case when user is blocked (for better user comprehension) + if (errorMessage !== '' && errorMessage.startsWith('BLOCKED USER')) { + const blockedMessage = this._patronBlockedMessagePipe.transform(this.patron); + this._toastService.error( + `${this._translate.instant('Checkout not possible.')} ${blockedMessage}`, + this._translate.instant('Circulation') + ); + } else { + this._toastService.error( + this._translate.instant('Checkout is not allowed by circulation policy'), + this._translate.instant('Checkout') + ); + } } else { this._toastService.error( this._translate.instant('An error occured on the server: ') + errorMessage, diff --git a/projects/admin/src/app/circulation/patron/main/main.component.html b/projects/admin/src/app/circulation/patron/main/main.component.html index c54432c9e..c6135d659 100644 --- a/projects/admin/src/app/circulation/patron/main/main.component.html +++ b/projects/admin/src/app/circulation/patron/main/main.component.html @@ -25,6 +25,12 @@
+
+ +
+
diff --git a/projects/admin/src/app/record/detail-view/patron-detail-view/patron-detail-view.component.html b/projects/admin/src/app/record/detail-view/patron-detail-view/patron-detail-view.component.html index a59779e30..92d439adc 100644 --- a/projects/admin/src/app/record/detail-view/patron-detail-view/patron-detail-view.component.html +++ b/projects/admin/src/app/record/detail-view/patron-detail-view/patron-detail-view.component.html @@ -15,44 +15,48 @@  along with this program. If not, see . --> - -

{{ record.metadata.last_name }} {{ record.metadata.first_name }}

+ +

{{ patron.last_name }} {{ patron.first_name }}

+ +
-
+
{{ 'Barcode' | translate }}:
- {{ record.metadata.barcode }} + {{ patron.barcode }}
-
+
{{ 'Type' | translate }}:
- {{ record.metadata.patron_type.pid | getRecord: 'patron_types' : 'field' : 'name' | async }} + {{ patron.patron_type.pid | getRecord: 'patron_types' : 'field' : 'name' | async }}
-
+
{{ 'Library' | translate }}:
- {{ record.metadata.library.pid | getRecord: 'libraries' : 'field' : 'name' | async }} + {{ patron.library.pid | getRecord: 'libraries' : 'field' : 'name' | async }}
-
+
{{ 'Phone' | translate }}:
- {{ record.metadata.phone }} + {{ patron.phone }}
@@ -61,7 +65,7 @@

{{ record.metadata.last_name }} {{ record.metadata.first_name } {{ 'Email' | translate }}:
- {{ record.metadata.email }} + {{ patron.email }}

@@ -70,7 +74,7 @@

{{ record.metadata.last_name }} {{ record.metadata.first_name } {{ 'Street' | translate }}:
- {{ record.metadata.street }} + {{ patron.street }}

@@ -79,17 +83,17 @@

{{ record.metadata.last_name }} {{ record.metadata.first_name } {{ 'City' | translate }}:
- {{ record.metadata.postal_code }} {{ record.metadata.city }} + {{ patron.postal_code }} {{ patron.city }}

- Role + Role Roles:
- + {{ role | translate }}{{ last ? '' : ', ' }}
diff --git a/projects/admin/src/app/record/detail-view/patron-detail-view/patron-detail-view.component.ts b/projects/admin/src/app/record/detail-view/patron-detail-view/patron-detail-view.component.ts index 47a39ca08..cd8f46b7f 100644 --- a/projects/admin/src/app/record/detail-view/patron-detail-view/patron-detail-view.component.ts +++ b/projects/admin/src/app/record/detail-view/patron-detail-view/patron-detail-view.component.ts @@ -14,10 +14,10 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnInit, OnDestroy } from '@angular/core'; import { DetailRecord } from '@rero/ng-core/lib/record/detail/view/detail-record'; import { Observable, Subscription } from 'rxjs'; -import { PatronService } from '../../../service/patron.service'; +import { User } from '../../../class/user'; @Component({ selector: 'admin-patron-detail-view', @@ -25,44 +25,31 @@ import { PatronService } from '../../../service/patron.service'; }) export class PatronDetailViewComponent implements OnInit, DetailRecord, OnDestroy { - /** Observable resolving record data */ + /** Data from patron we received */ record$: Observable; - /** Record subscription */ - private _recordObs: Subscription; - - /** Document record */ - record: any; + /** Current displayed/used patron */ + patron: User; /** record type */ type: string; - /** Constructor - * @param _patronService : PatronService - */ - constructor(private _patronService: PatronService) { } + /** Subscription to (un)follow the record$ Observable */ + private _subscription$ = new Subscription(); /** - * Init + * Current patron initialization. */ ngOnInit() { - this._recordObs = this.record$.subscribe(record => { - this.record = record; - this._patronService.setRecord(record); + this._subscription$ = this.record$.subscribe(record => { + this.patron = new User(record.metadata); }); } /** - * Destroy - */ - ngOnDestroy(): void { - this._recordObs.unsubscribe(); - } - - /** Check if the current logged user has a specific role - * @return True | False depending if the current logged user has the desired role + * Unsubscribe observable when destroying the PatronDetailViewComponent */ - hasRole(role: string): boolean { - return this._patronService.hasRole(role); + ngOnDestroy() { + this._subscription$.unsubscribe(); } } diff --git a/projects/admin/src/app/routes/patrons-route.ts b/projects/admin/src/app/routes/patrons-route.ts index 28ef0ae29..465349853 100644 --- a/projects/admin/src/app/routes/patrons-route.ts +++ b/projects/admin/src/app/routes/patrons-route.ts @@ -51,7 +51,14 @@ export class PatronsRoute extends BaseRoute implements RouteInterface { detailComponent: PatronDetailViewComponent, canUpdate: (record: any) => this._routeToolService.canUpdate(record, this.recordType), canDelete: (record: any) => this._routeToolService.canDelete(record, this.recordType), - aggregationsExpand: ['roles'] + aggregationsExpand: ['roles'], + // Clean-up 'blocked_note' field content if blocked is false. + postprocessRecordEditor: (record: any) => { + if (record.blocked === false) { + delete record.blocked_note; + } + return record; + }, } ] } diff --git a/projects/admin/src/app/service/patron.service.ts b/projects/admin/src/app/service/patron.service.ts index ef006ae51..da2c617d1 100644 --- a/projects/admin/src/app/service/patron.service.ts +++ b/projects/admin/src/app/service/patron.service.ts @@ -37,25 +37,6 @@ export class PatronService { private recordService: RecordService ) {} - /** - * Set Patron record - * @param patron - patron record - */ - setRecord(patron: any) { - this._patron = patron.metadata; - } - - /** - * has role - * @param role - name of role - */ - hasRole(role: string) { - if (this._patron && this._patron.roles) { - return this._patron.roles.some((r: string) => r === role); - } - return false; - } - /** * Get Current Patron * @return Observable diff --git a/projects/admin/src/app/shared/shared-pipes.module.ts b/projects/admin/src/app/shared/shared-pipes.module.ts index 61806e9a5..bf9a0991d 100644 --- a/projects/admin/src/app/shared/shared-pipes.module.ts +++ b/projects/admin/src/app/shared/shared-pipes.module.ts @@ -19,17 +19,20 @@ import { NgModule } from '@angular/core'; import { AuthorNameTranslatePipe } from '../pipe/author-name-translate.pipe'; import { MainTitlePipe } from '../pipe/main-title.pipe'; import { ProvisionActivityPipe } from '../pipe/provision-activity.pipe'; +import { PatronBlockedMessagePipe } from '../pipe/patron-blocked-message.pipe'; @NgModule({ declarations: [ AuthorNameTranslatePipe, MainTitlePipe, - ProvisionActivityPipe + ProvisionActivityPipe, + PatronBlockedMessagePipe ], exports: [ AuthorNameTranslatePipe, MainTitlePipe, - ProvisionActivityPipe + ProvisionActivityPipe, + PatronBlockedMessagePipe ] }) export class SharedPipesModule {} diff --git a/projects/admin/src/app/translate/i18n/de.json b/projects/admin/src/app/translate/i18n/de.json index 30924f114..e6ba33b55 100644 --- a/projects/admin/src/app/translate/i18n/de.json +++ b/projects/admin/src/app/translate/i18n/de.json @@ -43,6 +43,7 @@ "Checkout duration is required.": "Ausleihdauer ist erforderlich.", "Checkout impossible: the item is requested by another patron": "Ausleihe nicht möglich: das Exemplar ist von einem anderen Leser bestellt.", "Checkout is not allowed by circulation policy": "Ausleihe von der Ausleihpolitik nicht erlaubt", + "Checkout not possible.": "Checkout not possible.", "Circulation": "Ausleihe", "Circulation Policy": "Ausleihpolitik", "Circulation categories": "Ausleihkategorien", @@ -213,6 +214,7 @@ "Publication": "Publication", "Quantity": "Anzahl", "RERO ILS administration": "RERO ILS Administration", + "Reason": "Reason", "Reason of dispute": "Grund des Streits", "Record Updated!": "Datensatz aktualisiert!", "Record created!": "Datensatz erstellt!", @@ -269,6 +271,7 @@ "The record has been harvested": "Der Datensatz wurde gesammelt", "The request cannot be cancelled": "The request cannot be cancelled", "The two periods are overlapping.": "Die Zeiträume überlappen sich.", + "This patron is currently blocked.": "This patron is currently blocked.", "Title": "Titel", "Title is required.": "Titel ist erforderlich.", "To pick up": "Zur Abholung", diff --git a/projects/admin/src/app/translate/i18n/en.json b/projects/admin/src/app/translate/i18n/en.json index abd075fef..ab36c95c2 100644 --- a/projects/admin/src/app/translate/i18n/en.json +++ b/projects/admin/src/app/translate/i18n/en.json @@ -43,6 +43,7 @@ "Checkout duration is required.": "Checkout duration is required.", "Checkout impossible: the item is requested by another patron": "Checkout impossible: the item is requested by another patron", "Checkout is not allowed by circulation policy": "Checkout is not allowed by circulation policy", + "Checkout not possible.": "Checkout not possible.", "Circulation": "Circulation", "Circulation Policy": "Circulation Policy", "Circulation categories": "Circulation categories", @@ -213,6 +214,7 @@ "Publication": "Publication", "Quantity": "Quantity", "RERO ILS administration": "RERO ILS administration", + "Reason": "Reason", "Reason of dispute": "Reason of dispute", "Record Updated!": "Record Updated!", "Record created!": "Record created!", @@ -269,6 +271,7 @@ "The record has been harvested": "The record has been harvested", "The request cannot be cancelled": "The request cannot be cancelled", "The two periods are overlapping.": "The two periods are overlapping.", + "This patron is currently blocked.": "This patron is currently blocked.", "Title": "Title", "Title is required.": "Title is required.", "To pick up": "To pick up", diff --git a/projects/admin/src/app/translate/i18n/en_US.json b/projects/admin/src/app/translate/i18n/en_US.json index 1db813275..4616e543f 100644 --- a/projects/admin/src/app/translate/i18n/en_US.json +++ b/projects/admin/src/app/translate/i18n/en_US.json @@ -43,6 +43,7 @@ "Checkout duration is required.": "Checkout duration is required.", "Checkout impossible: the item is requested by another patron": "Checkout impossible: the item is requested by another patron", "Checkout is not allowed by circulation policy": "Checkout is not allowed by circulation policy", + "Checkout not possible.": "Checkout not possible.", "Circulation": "Circulation", "Circulation Policy": "Circulation Policy", "Circulation categories": "Circulation categories", @@ -213,6 +214,7 @@ "Publication": "Publication", "Quantity": "Quantity", "RERO ILS administration": "RERO ILS administration", + "Reason": "Reason", "Reason of dispute": "Reason of dispute", "Record Updated!": "Record Updated!", "Record created!": "Record created!", @@ -269,6 +271,7 @@ "The record has been harvested": "The record has been harvested", "The request cannot be cancelled": "The request cannot be cancelled", "The two periods are overlapping.": "The two periods are overlapping.", + "This patron is currently blocked.": "This patron is currently blocked.", "Title": "Title", "Title is required.": "Title is required.", "To pick up": "To pick up", diff --git a/projects/admin/src/app/translate/i18n/es.json b/projects/admin/src/app/translate/i18n/es.json index 39783e795..3acb066ee 100644 --- a/projects/admin/src/app/translate/i18n/es.json +++ b/projects/admin/src/app/translate/i18n/es.json @@ -43,6 +43,7 @@ "Checkout duration is required.": "La duración del préstamo est obligatorio.", "Checkout impossible: the item is requested by another patron": "Préstamo imposible : el ejemplar es reservado por otro usuario", "Checkout is not allowed by circulation policy": "El préstamo no está permitido por la política de circulación", + "Checkout not possible.": "Checkout not possible.", "Circulation": "Circulación", "Circulation Policy": "Política de circulación", "Circulation categories": "Categoría de préstamo", @@ -213,6 +214,7 @@ "Publication": "Publication", "Quantity": "Cantidad", "RERO ILS administration": "Administración RERO ILS", + "Reason": "Reason", "Reason of dispute": "Motivo del litigio", "Record Updated!": "¡El recurso ha sido actualizado!", "Record created!": "¡El recurso ha sido creado!", @@ -269,6 +271,7 @@ "The record has been harvested": "El recurso ha sido importado.", "The request cannot be cancelled": "The request cannot be cancelled", "The two periods are overlapping.": "Los dos períodos se superponen.", + "This patron is currently blocked.": "This patron is currently blocked.", "Title": "Título", "Title is required.": "El título es obligatorio.", "To pick up": "Recogida", diff --git a/projects/admin/src/app/translate/i18n/fr.json b/projects/admin/src/app/translate/i18n/fr.json index 5951bb03c..b5543e9f0 100644 --- a/projects/admin/src/app/translate/i18n/fr.json +++ b/projects/admin/src/app/translate/i18n/fr.json @@ -43,6 +43,7 @@ "Checkout duration is required.": "La durée du prêt est obligatoire.", "Checkout impossible: the item is requested by another patron": "Prêt impossible: l'exemplaire est demandé par un autre lecteur", "Checkout is not allowed by circulation policy": "Prêt non autorisé par la politique de prêt", + "Checkout not possible.": "Checkout not possible.", "Circulation": "Prêt", "Circulation Policy": "Politique de prêt", "Circulation categories": "Catégories de circulation", @@ -213,6 +214,7 @@ "Publication": "Publication", "Quantity": "Quantité", "RERO ILS administration": "Interface professionnelle de RERO ILS", + "Reason": "Raison", "Reason of dispute": "Motif du litige", "Record Updated!": "La ressource a été mise à jour!", "Record created!": "La ressource a été créée!", @@ -269,6 +271,7 @@ "The record has been harvested": "L'enregistrement a été importé", "The request cannot be cancelled": "The request cannot be cancelled", "The two periods are overlapping.": "Les deux périodes se chevauchent.", + "This patron is currently blocked.": "Ce lecteur est actuellement bloqué.", "Title": "Titre", "Title is required.": "Le titre est obligatoire.", "To pick up": "A retirer", diff --git a/projects/admin/src/app/translate/i18n/it.json b/projects/admin/src/app/translate/i18n/it.json index 5c00d2da1..8afff42e1 100644 --- a/projects/admin/src/app/translate/i18n/it.json +++ b/projects/admin/src/app/translate/i18n/it.json @@ -43,6 +43,7 @@ "Checkout duration is required.": "La durata di prestito è richiesta.", "Checkout impossible: the item is requested by another patron": "Prestito impossibile: l'esemplare è richiesto da un altro lettore", "Checkout is not allowed by circulation policy": "Prestito non consentito dalla politica di prestito", + "Checkout not possible.": "Checkout not possible.", "Circulation": "Prestito", "Circulation Policy": "Politica di prestito", "Circulation categories": "Categorie di prestito", @@ -213,6 +214,7 @@ "Publication": "Publication", "Quantity": "Quantità", "RERO ILS administration": "Amministrazione RERO ILS", + "Reason": "Reason", "Reason of dispute": "Motivo della controversia", "Record Updated!": "Il record è stato aggiornato!", "Record created!": "Record creato!", @@ -269,6 +271,7 @@ "The record has been harvested": "Il record è stato raccolto", "The request cannot be cancelled": "The request cannot be cancelled", "The two periods are overlapping.": "I due periodi si sovrappongono.", + "This patron is currently blocked.": "This patron is currently blocked.", "Title": "Titolo", "Title is required.": "Il titolo è richiesto.", "To pick up": "Da ritirare",