From ea9db8163650b507af5e226871194b1661a311ad Mon Sep 17 00:00:00 2001 From: Alicia Zangger Date: Tue, 20 Oct 2020 10:47:08 +0200 Subject: [PATCH] request: allow cancellation when item is at desk * Updates 'cancel request' permissions to allow the cancellation of an item 'at desk'. * Adds a method to update the item detailed view after a cancel request. * Adds a flash message to inform the user about the item status. * Moves 'cancel' and 'update' logic from the item-transaction component (list item) to the item-transactions (list) component for a better understanding and to clean the code. * Closes rero/rero-ils#1293. Co-Authored-by: Alicia Zangger --- .../item-detail-view.component.html | 5 +- .../item-detail-view.component.ts | 30 ++++--- .../item-transaction.component.html | 2 +- .../item-transaction.component.ts | 59 +++++--------- .../item-transactions.component.html | 3 +- .../item-transactions.component.ts | 80 ++++++++++++++++--- .../admin/src/app/service/items.service.ts | 2 +- 7 files changed, 117 insertions(+), 64 deletions(-) diff --git a/projects/admin/src/app/record/detail-view/item-detail-view/item-detail-view.component.html b/projects/admin/src/app/record/detail-view/item-detail-view/item-detail-view.component.html index b09c377e0..2be539911 100644 --- a/projects/admin/src/app/record/detail-view/item-detail-view/item-detail-view.component.html +++ b/projects/admin/src/app/record/detail-view/item-detail-view/item-detail-view.component.html @@ -141,5 +141,8 @@

Issue data

- + diff --git a/projects/admin/src/app/record/detail-view/item-detail-view/item-detail-view.component.ts b/projects/admin/src/app/record/detail-view/item-detail-view/item-detail-view.component.ts index 1a4cb33f1..0dd7f74a2 100644 --- a/projects/admin/src/app/record/detail-view/item-detail-view/item-detail-view.component.ts +++ b/projects/admin/src/app/record/detail-view/item-detail-view/item-detail-view.component.ts @@ -17,9 +17,8 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { extractIdOnRef, RecordService } from '@rero/ng-core'; import { DetailRecord } from '@rero/ng-core/lib/record/detail/view/detail-record'; -import { forkJoin, Observable, Subscription } from 'rxjs'; +import { Observable, Subscription } from 'rxjs'; import { IssueItemStatus } from '../../../class/items'; -import { LoanService } from '../../../service/loan.service'; @Component({ selector: 'admin-item-detail-view', @@ -54,24 +53,19 @@ export class ItemDetailViewComponent implements DetailRecord, OnInit, OnDestroy /** * Constructor - * @param recordService - RecordService - * @param loanService - LoanService + * @param _recordService - RecordService */ constructor( - private recordService: RecordService, - private loanService: LoanService + private _recordService: RecordService ) {} ngOnInit() { - this._recordObs = this.record$.subscribe( record => { + this._recordObs = this.record$.subscribe(record => { this.record = record; - const numberOfRequest$ = this.loanService.numberOfRequests$(record.metadata.pid); - const locationRecord$ = this.recordService.getRecord('locations', record.metadata.location.pid); - forkJoin([numberOfRequest$, locationRecord$]).subscribe( - ([numberOfRequest, location]) => { - this.numberOfRequests = numberOfRequest; + this._recordService.getRecord('locations', record.metadata.location.pid).subscribe( + (location) => { this.location = location; - this.recordService.getRecord('libraries', extractIdOnRef(location.metadata.library.$ref)).subscribe( + this._recordService.getRecord('libraries', extractIdOnRef(location.metadata.library.$ref)).subscribe( library => this.library = library ); } @@ -82,4 +76,14 @@ export class ItemDetailViewComponent implements DetailRecord, OnInit, OnDestroy ngOnDestroy() { this._recordObs.unsubscribe(); } + + /** + * Update item status + */ + updateItemStatus() { + this._recordService.getRecord('items', this.record.metadata.pid).subscribe((item: any) => { + this.record.metadata.status = item.metadata.status; + this.record.metadata.available = item.metadata.available; + }); + } } diff --git a/projects/admin/src/app/record/detail-view/item-detail-view/item-transaction/item-transaction.component.html b/projects/admin/src/app/record/detail-view/item-detail-view/item-transaction/item-transaction.component.html index 7af0fc8a8..139c4fd8d 100644 --- a/projects/admin/src/app/record/detail-view/item-detail-view/item-transaction/item-transaction.component.html +++ b/projects/admin/src/app/record/detail-view/item-detail-view/item-transaction/item-transaction.component.html @@ -43,7 +43,7 @@ diff --git a/projects/admin/src/app/record/detail-view/item-detail-view/item-transaction/item-transaction.component.ts b/projects/admin/src/app/record/detail-view/item-detail-view/item-transaction/item-transaction.component.ts index 9f4322351..93a76eace 100644 --- a/projects/admin/src/app/record/detail-view/item-detail-view/item-transaction/item-transaction.component.ts +++ b/projects/admin/src/app/record/detail-view/item-detail-view/item-transaction/item-transaction.component.ts @@ -16,12 +16,9 @@ */ import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; -import { DialogService, RecordService } from '@rero/ng-core'; -import { ToastrService } from 'ngx-toastr'; +import { DialogService } from '@rero/ng-core'; import { LoanState } from 'projects/admin/src/app/class/items'; -import { LoanService } from 'projects/admin/src/app/service/loan.service'; import { UserService } from 'projects/admin/src/app/service/user.service'; -import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { ItemsService } from 'projects/admin/src/app/service/items.service'; @@ -80,7 +77,12 @@ export class ItemTransactionComponent implements OnInit, OnDestroy { /** * Informs parent component to remove request when it is cancelled */ - @Output() removeRequest = new EventEmitter(); + @Output() cancelRequestEvent = new EventEmitter(); + + /** + * Informs parent component to update pickup location + */ + @Output() updatePickupLocationEvent = new EventEmitter(); /** * On init hook @@ -105,17 +107,13 @@ export class ItemTransactionComponent implements OnInit, OnDestroy { /** * constructor - * @param _loanService - LoanService * @param _userService - User service - * @param _toastrService - ToastrService * @param _translateService - TranslateService * @param _dialogService: DialogService * @param _itemService: ItemsService */ constructor( - private _loanService: LoanService, private _userService: UserService, - private _toastrService: ToastrService, private _translateService: TranslateService, private _dialogService: DialogService, private _itemService: ItemsService @@ -141,7 +139,8 @@ export class ItemTransactionComponent implements OnInit, OnDestroy { // No permission API in backend // Allowed when loan state is PENDING or ITEM_IN_TRANSIT_FOR_PICKUP according to actions.md return this.transaction.metadata.state === LoanState.PENDING - || this.transaction.metadata.state === LoanState.ITEM_IN_TRANSIT_FOR_PICKUP; + || this.transaction.metadata.state === LoanState.ITEM_IN_TRANSIT_FOR_PICKUP + || this.transaction.metadata.state === LoanState.ITEM_AT_DESK; } /** @@ -172,43 +171,27 @@ export class ItemTransactionComponent implements OnInit, OnDestroy { this._dialogService.show(config).subscribe((confirm: boolean) => { if (confirm) { - this.cancelRequest(); + this.emitCancelRequest(); } }); } /** - * Cancel request + * Inform parent to cancel the request */ - cancelRequest() { - this._loanService - .cancelLoan( - this.itemPid, - this.transaction.metadata.pid, - this._currentUser.currentLibrary - ) - .subscribe((itemData: any) => { - this.removeRequest.emit(true); - }); + emitCancelRequest() { + this.cancelRequestEvent.emit(this.transaction); } /** - * Update pickup location - * @param pickupLocationPid - pickup location pid to change - */ - updateRequest(pickupLocationPid: string) { - this._loanService - .updateLoanPickupLocation( - this.transaction.metadata.pid, - pickupLocationPid - ) - .subscribe((data: any) => { - this._toastrService.success( - this._translateService.instant('The pickup location has been changed.'), - this._translateService.instant('Request') - ); - this.transaction.metadata = data; - }); + * Inform parent to cancel the request + */ + emitUpdatePickupLocation(pickupLocationPid: string) { + const data = { + pickupLocationPid, + transaction: this.transaction + }; + this.updatePickupLocationEvent.emit(data); } /** diff --git a/projects/admin/src/app/record/detail-view/item-detail-view/item-transactions/item-transactions.component.html b/projects/admin/src/app/record/detail-view/item-detail-view/item-transactions/item-transactions.component.html index 52645723f..9ae2cb11b 100644 --- a/projects/admin/src/app/record/detail-view/item-detail-view/item-transactions/item-transactions.component.html +++ b/projects/admin/src/app/record/detail-view/item-detail-view/item-transactions/item-transactions.component.html @@ -64,7 +64,8 @@ [background]="i % 2" [transaction]="request" [itemPid]="item.metadata.pid" - (removeRequest)="updateRequestList()" + (cancelRequestEvent)="cancelRequest($event)" + (updatePickupLocationEvent)="updateRequestPickupLocation($event)" > diff --git a/projects/admin/src/app/record/detail-view/item-detail-view/item-transactions/item-transactions.component.ts b/projects/admin/src/app/record/detail-view/item-detail-view/item-transactions/item-transactions.component.ts index d033e2cca..2e5aadac4 100644 --- a/projects/admin/src/app/record/detail-view/item-detail-view/item-transactions/item-transactions.component.ts +++ b/projects/admin/src/app/record/detail-view/item-detail-view/item-transactions/item-transactions.component.ts @@ -14,9 +14,12 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; import { BsModalService } from 'ngx-bootstrap/modal'; +import { ToastrService } from 'ngx-toastr'; import { LoanService } from 'projects/admin/src/app/service/loan.service'; +import { UserService } from 'projects/admin/src/app/service/user.service'; import { Observable } from 'rxjs'; import { first } from 'rxjs/operators'; import { ItemRequestComponent } from '../../document-detail-view/item-request/item-request.component'; @@ -33,6 +36,11 @@ export class ItemTransactionsComponent implements OnInit { */ @Input() item: any; + /** + * Informs parent component that a request has been cancelled + */ + @Output() cancelRequestEvent = new EventEmitter(); + /** * Borrowed item */ @@ -43,31 +51,36 @@ export class ItemTransactionsComponent implements OnInit { */ requestedBy$: Observable; + /** + * Current user + */ + private _currentUser: any; + /** * Constructor * @param loanService - LoanService * @param _modalService - BsModalService + * @param _toastrService - ToastrService + * @param _translateService - TranslateService + * @param _userService - UserService */ constructor( private _loanService: LoanService, - private _modalService: BsModalService + private _modalService: BsModalService, + private _toastrService: ToastrService, + private _translateService: TranslateService, + private _userService: UserService ) { } /** * On init hook */ ngOnInit() { + this._currentUser = this._userService.getCurrentUser(); this.borrowedBy$ = this._loanService.borrowedBy$(this.item.metadata.pid); this.requestedBy$ = this._loanService.requestedBy$(this.item.metadata.pid); } - /** - * Update request list - */ - updateRequestList() { - this.requestedBy$ = this._loanService.requestedBy$(this.item.metadata.pid); - } - /** * Add request on item * @param itemPid - string @@ -80,4 +93,53 @@ export class ItemTransactionsComponent implements OnInit { this.updateRequestList(); }); } + + /** + * Cancel request + * @param transaction - request to cancel + */ + cancelRequest(transaction: any) { + this._loanService + .cancelLoan( + this.item.pid, + transaction.metadata.pid, + this._currentUser.currentLibrary + ) + .subscribe((itemData: any) => { + const status = itemData.status; + this._toastrService.warning( + this._translateService.instant('The item is ' + status), + // this._translateService.instant('The item is {{ status }}', { status }), + this._translateService.instant('Request') + ); + this.cancelRequestEvent.emit(); + this.updateRequestList(); + }); + } + + /** + * Update request pickup location + * @param pickupLocationPid - pickup location pid to change + */ + updateRequestPickupLocation(data: any) { + this._loanService + .updateLoanPickupLocation( + data.transaction.metadata.pid, + data.pickupLocationPid + ) + .subscribe((response: any) => { + this._toastrService.success( + this._translateService.instant('The pickup location has been changed.'), + this._translateService.instant('Request') + ); + this.updateRequestList(); + }); + } + + /** + * Update request list + */ + updateRequestList() { + this.requestedBy$ = this._loanService.requestedBy$(this.item.metadata.pid); + } } diff --git a/projects/admin/src/app/service/items.service.ts b/projects/admin/src/app/service/items.service.ts index 3b1ee2f5b..59f7a836d 100644 --- a/projects/admin/src/app/service/items.service.ts +++ b/projects/admin/src/app/service/items.service.ts @@ -18,7 +18,7 @@ import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { RecordService } from '@rero/ng-core'; -import { Observable, of } from 'rxjs'; +import { Observable, of, Subject } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { Item, ItemAction, ItemNoteType, ItemStatus } from '../class/items'; import { UserService } from './user.service';