diff --git a/package-lock.json b/package-lock.json index 145d124cc..fd0c9dc93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,6 @@ "lodash-es": "^4.17.21", "luxon": "^3.5.0", "marked": "^10.0.0", - "moment": "^2.30.1", "ngx-bootstrap": "^12.0.0", "ngx-spinner": "^16.0.0", "primeflex": "^3.3.1", @@ -11370,14 +11369,6 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "engines": { - "node": "*" - } - }, "node_modules/mrmime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", diff --git a/package.json b/package.json index 733e09f3d..a0cdd12ea 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,6 @@ "lodash-es": "^4.17.21", "luxon": "^3.5.0", "marked": "^10.0.0", - "moment": "^2.30.1", "ngx-bootstrap": "^12.0.0", "ngx-spinner": "^16.0.0", "primeflex": "^3.3.1", diff --git a/projects/admin/src/app/acquisition/components/receipt/receipt-form/order-receipt.ts b/projects/admin/src/app/acquisition/components/receipt/receipt-form/order-receipt.ts index 302760057..80364f282 100644 --- a/projects/admin/src/app/acquisition/components/receipt/receipt-form/order-receipt.ts +++ b/projects/admin/src/app/acquisition/components/receipt/receipt-form/order-receipt.ts @@ -1,6 +1,6 @@ /* * RERO ILS UI - * Copyright (C) 2021 RERO + * Copyright (C) 2021-2024 RERO * * 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 @@ -17,9 +17,9 @@ import { inject, Injectable } from '@angular/core'; import { ApiService } from '@rero/ng-core'; -import moment from 'moment'; import { IAcqNote } from '../../../classes/common'; import { AcqReceiptAmountAdjustment, IAcqReceipt, IAcqReceiptLine } from '../../../classes/receipt'; +import { DateTime } from 'luxon'; /** Interface for Receipt data */ export interface IAcqReceiptModel { @@ -82,7 +82,7 @@ export class OrderReceipt { acqOrderRef: null, libraryRef: null, organisationRef: null, - receiptDate: moment().format(moment.HTML5_FMT.DATE), + receiptDate: DateTime.now().toISODate(), exchangeRate: 1, reference: null, amountAdjustments: [], diff --git a/projects/admin/src/app/api/library-api.service.ts b/projects/admin/src/app/api/library-api.service.ts index ebb4f13dd..dec3b790e 100644 --- a/projects/admin/src/app/api/library-api.service.ts +++ b/projects/admin/src/app/api/library-api.service.ts @@ -15,10 +15,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import { HttpClient } from '@angular/common/http'; import { inject, Injectable } from '@angular/core'; import { RecordService } from '@rero/ng-core'; -import moment from 'moment'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -27,7 +25,6 @@ import { map } from 'rxjs/operators'; }) export class LibraryApiService { - private http: HttpClient = inject(HttpClient); private recordService: RecordService = inject(RecordService); /** @@ -39,19 +36,4 @@ export class LibraryApiService { return this.recordService.getRecord('libraries', pid) .pipe(map(record => record.metadata)); } - - /** - * Allow to get the closed date between two dates for a specific library - * @param libraryPid: the library pid - * @param from: the lower interval (optional) - * @param until: the upper interval (optional) - */ - getClosedDates(libraryPid: string, from?: string, until?: string): Observable> { - from = from || moment().subtract(1, 'month'); - until = until || moment().add(1, 'year'); - return this.http.get(`/api/library/${libraryPid}/closed_dates`, {params: {from, until}}).pipe( - map((data: any) => data.closed_dates), - map((dates: [string]) => dates.map(dateStr => moment(dateStr))) - ); - } } diff --git a/projects/admin/src/app/api/operation-logs-api.service.ts b/projects/admin/src/app/api/operation-logs-api.service.ts index 4eca6a7ac..ad0a16747 100644 --- a/projects/admin/src/app/api/operation-logs-api.service.ts +++ b/projects/admin/src/app/api/operation-logs-api.service.ts @@ -19,9 +19,9 @@ import { inject, Injectable } from '@angular/core'; import { Record, RecordService } from '@rero/ng-core'; import { Error } from '@rero/ng-core/lib/error/error'; import { BaseApi } from '@rero/shared'; -import moment from 'moment'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { DateTime } from 'luxon'; @Injectable({ providedIn: 'root' @@ -89,7 +89,7 @@ export class OperationLogsApiService extends BaseApi { * @return Observable */ getCheckInHistory(patronPid: string, page: number, itemsPerPage: number = 10): Observable { - const date = moment().subtract(6, 'months').utc().format('YYYY-MM-DDTHH:mm:ss'); + const date = DateTime.now().minus({ months: 6 }).toISO(); const query = `_exists_:loan AND record.type:loan AND loan.patron.pid:${patronPid} AND loan.trigger:checkin AND date:[${date} TO *]`; return this.recordService.getRecords( 'operation_logs', query, page, itemsPerPage, undefined, undefined, BaseApi.reroJsonheaders, 'mostrecent'); diff --git a/projects/admin/src/app/circulation/circulation-routing.module.ts b/projects/admin/src/app/circulation/circulation-routing.module.ts index b609ece14..c2de9654c 100644 --- a/projects/admin/src/app/circulation/circulation-routing.module.ts +++ b/projects/admin/src/app/circulation/circulation-routing.module.ts @@ -29,6 +29,7 @@ import { PatronTransactionsComponent } from './patron/patron-transactions/patron import { PendingComponent } from './patron/pending/pending.component'; import { PickupComponent } from './patron/pickup/pickup.component'; import { ProfileComponent } from './patron/profile/profile.component'; +import { keepHistoryGuard } from './guard/keep-history.guard'; const routes: Routes = [ { @@ -78,7 +79,7 @@ const routes: Routes = [ { path: 'history', component: HistoryComponent, - canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } + canActivate: [ keepHistoryGuard, PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } } ] }, { diff --git a/projects/admin/src/app/circulation/guard/keep-history.guard.spec.ts b/projects/admin/src/app/circulation/guard/keep-history.guard.spec.ts new file mode 100644 index 000000000..d968b463e --- /dev/null +++ b/projects/admin/src/app/circulation/guard/keep-history.guard.spec.ts @@ -0,0 +1,33 @@ +/* + * RERO ILS UI + * Copyright (C) 2024 RERO + * + * 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 . + */ +import { TestBed } from '@angular/core/testing'; +import { CanActivateFn } from '@angular/router'; + +import { keepHistoryGuard } from './keep-history.guard'; + +describe('keepHistoryGuard', () => { + const executeGuard: CanActivateFn = (...guardParameters) => + TestBed.runInInjectionContext(() => keepHistoryGuard(...guardParameters)); + + beforeEach(() => { + TestBed.configureTestingModule({}); + }); + + it('should be created', () => { + expect(executeGuard).toBeTruthy(); + }); +}); diff --git a/projects/admin/src/app/circulation/guard/keep-history.guard.ts b/projects/admin/src/app/circulation/guard/keep-history.guard.ts new file mode 100644 index 000000000..2b882f343 --- /dev/null +++ b/projects/admin/src/app/circulation/guard/keep-history.guard.ts @@ -0,0 +1,33 @@ +/* + * RERO ILS UI + * Copyright (C) 2024 RERO + * + * 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 . + */ +import { inject } from '@angular/core'; +import { CanActivateFn, Router } from '@angular/router'; +import { PatronService } from '@app/admin/service/patron.service'; +import { map } from 'rxjs'; + +export const keepHistoryGuard: CanActivateFn = (route, state) => { + const patronService: PatronService = inject(PatronService); + const router: Router = inject(Router); + + const patronPid = state.url.split('/').splice(-2)[0]; + return patronService.getPatron(patronPid).pipe(map((patron: any) => { + if (!patron.keep_history) { + router.navigate(['/errors/403'], { skipLocationChange: true }); + } + return patron.keep_history + })); +}; diff --git a/projects/admin/src/app/circulation/main-request/main-request.component.html b/projects/admin/src/app/circulation/main-request/main-request.component.html index 11dbee3c2..d44b75119 100644 --- a/projects/admin/src/app/circulation/main-request/main-request.component.html +++ b/projects/admin/src/app/circulation/main-request/main-request.component.html @@ -14,7 +14,6 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> -
) { this.items = items.sort((a, b) => { - const aTime = moment(a.loan.transaction_date); - const bTime = moment(b.loan.transaction_date); + const aTime = DateTime.fromISO(a.loan.transaction_date); + const bTime = DateTime.fromISO(b.loan.transaction_date); switch (this.sortCriteria) { case '-requestdate': return bTime.diff(aTime); case 'callnumber': diff --git a/projects/admin/src/app/circulation/patron/loan/fixed-date-form/fixed-date-form.component.ts b/projects/admin/src/app/circulation/patron/loan/fixed-date-form/fixed-date-form.component.ts index 13ab3c87d..1f7914ef7 100644 --- a/projects/admin/src/app/circulation/patron/loan/fixed-date-form/fixed-date-form.component.ts +++ b/projects/admin/src/app/circulation/patron/loan/fixed-date-form/fixed-date-form.component.ts @@ -36,9 +36,6 @@ export class FixedDateFormComponent implements OnInit, OnDestroy { private userService: UserService = inject(UserService); private recordService: RecordService = inject(RecordService); - /** the date format to used */ - static DATE_FORMAT = 'YYYY-MM-DD'; - // COMPONENT ATTRIBUTES ==================================== /** form group */ formGroup: FormGroup = new FormGroup({ @@ -46,7 +43,7 @@ export class FixedDateFormComponent implements OnInit, OnDestroy { Validators.required, DateValidators.minimumDateValidator( new Date(), - FixedDateFormComponent.DATE_FORMAT + DateValidators.DATE_FORMAT ) ]), remember: new FormControl(false) diff --git a/projects/admin/src/app/circulation/patron/main/main.component.ts b/projects/admin/src/app/circulation/patron/main/main.component.ts index aa99e8a55..67086a003 100644 --- a/projects/admin/src/app/circulation/patron/main/main.component.ts +++ b/projects/admin/src/app/circulation/patron/main/main.component.ts @@ -167,9 +167,12 @@ export class MainComponent implements OnInit, OnDestroy { // null and this will cause error for navigation url construction this._unregisterShortcuts(); this._registerShortcuts(); - this.operationLogsApiService.getCheckInHistory(patron.pid, 1, 1).subscribe((result: any) => { - this.historyCount = this.recordService.totalHits(result.hits.total); - }); + // Load count history only if the patron has keep history + if (patron.keep_history) { + this.operationLogsApiService.getCheckInHistory(patron.pid, 1, 1).subscribe((result: any) => { + this.historyCount = this.recordService.totalHits(result.hits.total); + }); + } this.patronService.getCirculationInformations(patron.pid).subscribe((data) => { this.circulationService.clear(); this.feesTotalAmount = data.fees.engaged + data.fees.preview; diff --git a/projects/admin/src/app/classes/items.ts b/projects/admin/src/app/classes/items.ts index 4df5cbaf0..6800afb2f 100644 --- a/projects/admin/src/app/classes/items.ts +++ b/projects/admin/src/app/classes/items.ts @@ -1,6 +1,6 @@ /* * RERO ILS UI - * Copyright (C) 2019 RERO + * Copyright (C) 2019-2024 RERO * * 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 @@ -18,9 +18,9 @@ /* tslint:disable */ // required as json properties is not lowerCamelCase -import { Moment } from 'moment'; import { ItemStatus, User } from '@rero/shared'; -import { Loan } from './loans' +import { DateTime } from 'luxon'; +import { Loan } from './loans'; export enum ItemNoteType { GENERAL = 'general_note', @@ -98,7 +98,7 @@ export class Item { library: any; library_location_name: any; notes: ItemNote[]; - acquisition_date: Moment; + acquisition_date: DateTime; enumerationAndChronology: string; temporary_location?: any; diff --git a/projects/admin/src/app/classes/library.ts b/projects/admin/src/app/classes/library.ts index cb5b06939..4e2caad21 100644 --- a/projects/admin/src/app/classes/library.ts +++ b/projects/admin/src/app/classes/library.ts @@ -1,6 +1,6 @@ /* * RERO ILS UI - * Copyright (C) 2019-2023 RERO + * Copyright (C) 2019-2024 RERO * * 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 @@ -19,9 +19,9 @@ // required as json properties is not lowerCamelCase import { WeekDay } from '@angular/common'; -import * as moment from 'moment'; import { NotificationType } from './notification'; import { WeekDays } from './week-days'; +import { DateTime } from 'luxon'; export interface OpeningHours { @@ -136,7 +136,7 @@ export class Library { } return exception; }); - this.exception_dates = this.exception_dates.sort((a, b) => moment(a.start_date) - moment(b.start_date)); + this.exception_dates = this.exception_dates.sort((a, b) => DateTime.fromISO(a.start_date) - DateTime.fromISO(b.start_date)); } /** @@ -165,8 +165,8 @@ export class Library { if (exception.repeat && checkRepeat) { return false; } - const checked_date = (exception.end_date) ? moment(exception.end_date) : moment(exception.start_date); - return checked_date < moment(); + const checked_date = (exception.end_date) ? DateTime.fromISO(exception.end_date) : DateTime.fromISO(exception.start_date); + return checked_date < DateTime.now(); } // PRIVATE METHODS ================================================ @@ -201,7 +201,7 @@ export class Library { this.opening_hours.forEach(opening => { if (opening.times.length > 1) { opening.times.sort((a, b) => - moment(a.start_time, 'HH:mm').diff(moment(b.start_time, 'HH:mm'))); + DateTime.fromFormat(a.start_time, 'HH:mm').diff(DateTime.fromFormat(b.start_time, 'HH:mm'))); } }); } @@ -216,13 +216,13 @@ export class Library { if (!exception.repeat) { throw new Error('Unable to increment not repeatable exception date.'); } - const momentJsUnitMapper = {daily: 'd', weekly: 'w', monthly: 'M', yearly: 'y'}; - const unity = (momentJsUnitMapper.hasOwnProperty(exception.repeat.period)) - ? momentJsUnitMapper[exception.repeat.period] - : 'd'; - exception.start_date = moment(exception.start_date).add(exception.repeat.interval, unity).format('YYYY-MM-DD'); + const jsUnitMapper = {daily: 'days', weekly: 'weeks', monthly: 'months', yearly: 'years'}; + const unity = (jsUnitMapper.hasOwnProperty(exception.repeat.period)) + ? jsUnitMapper[exception.repeat.period] + : 'days'; + exception.start_date = DateTime.fromFormat(exception.start_date).plus({ [unity]: exception.repeat.interval }).format('yyyy-LL-dd'); if (exception.end_date) { - exception.end_date = moment(exception.end_date).add(exception.repeat.interval, unity).format('YYYY-MM-DD'); + exception.end_date = DateTime.fromFormat(exception.end_date).plus({ [unity]: exception.repeat.interval }).format('yyyy-LL-dd'); } return exception; } diff --git a/projects/admin/src/app/classes/loans.ts b/projects/admin/src/app/classes/loans.ts index 3a4fa6bf7..94a5dff6a 100644 --- a/projects/admin/src/app/classes/loans.ts +++ b/projects/admin/src/app/classes/loans.ts @@ -17,7 +17,7 @@ /* tslint:disable */ // required as json properties is not lowerCamelCase -import moment, { Moment } from 'moment'; +import { DateTime } from 'luxon'; // ENUM ======================================================================== /** All possible state about a loan */ @@ -54,13 +54,13 @@ export class LoanDestination { export class Loan { pid?: string; state: LoanState; - transaction_date?: Moment; + transaction_date?: DateTime; patron_pid?: string; document_pid?: string; item_pid?: {type: string, value: string}; - start_date?: Moment; - end_date?: Moment; - request_expire_date?: Moment; + start_date?: DateTime; + end_date?: DateTime; + request_expire_date?: DateTime; pickup_location_pid?: string; item_destination?: LoanDestination; transaction_location_pid?: string; @@ -71,24 +71,24 @@ export class Loan { */ constructor(obj?: any) { Object.assign(this, obj); - this.request_expire_date = Loan._convertToMoment(this.request_expire_date); - this.start_date = Loan._convertToMoment(this.start_date); - this.end_date = Loan._convertToMoment(this.end_date); - this.transaction_date = Loan._convertToMoment(this.transaction_date); + this.request_expire_date = Loan._convertToDate(this.request_expire_date); + this.start_date = Loan._convertToDate(this.start_date); + this.end_date = Loan._convertToDate(this.end_date); + this.transaction_date = Loan._convertToDate(this.transaction_date); } /** - * Convert a string representation of a date to a `moment` + * Convert a string representation of a date to a `DateTime` * @param data: the date to parse */ - private static _convertToMoment(data): moment|null { + private static _convertToDate(data?: string): DateTime|null { return (data) - ? moment(data) + ? DateTime.fromISO(data) : null; } /** Return the due date about the loan */ - get dueDate(): moment { + get dueDate(): DateTime { switch (this.state) { case LoanState.PENDING: return this.request_expire_date; case LoanState.ITEM_ON_LOAN: return this.end_date; @@ -99,7 +99,7 @@ export class Loan { /** Is the loan is expired or not ? */ public get expired(): boolean { return (this.dueDate) - ? this.dueDate.isBefore(new Date()) + ? this.dueDate < DateTime.now() : false; } } diff --git a/projects/admin/src/app/classes/notification.ts b/projects/admin/src/app/classes/notification.ts index d089af783..690b72d17 100644 --- a/projects/admin/src/app/classes/notification.ts +++ b/projects/admin/src/app/classes/notification.ts @@ -1,6 +1,6 @@ /* * RERO ILS UI - * Copyright (C) 2021 RERO + * Copyright (C) 2021-2024 RERO * * 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 @@ -18,8 +18,8 @@ /* tslint:disable */ // required as json properties is not lowerCamelCase -import { Moment } from 'moment'; import { ObjectReference } from '../../../../shared/src/lib/class/core'; +import { DateTime } from 'luxon'; export enum NotificationType { AT_DESK = 'at_desk', @@ -53,8 +53,8 @@ export class Notification { }; pid: string; - creation_date: Moment; - process_date?: Moment; + creation_date: DateTime; + process_date?: DateTime; notification_sent = false; notification_type: NotificationType; context: { diff --git a/projects/admin/src/app/classes/patron-transaction.ts b/projects/admin/src/app/classes/patron-transaction.ts index e573dd439..2de4375e4 100644 --- a/projects/admin/src/app/classes/patron-transaction.ts +++ b/projects/admin/src/app/classes/patron-transaction.ts @@ -1,6 +1,6 @@ /* * RERO ILS UI - * Copyright (C) 2019 RERO + * Copyright (C) 2019-2024 RERO * * 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 @@ -18,7 +18,7 @@ /* tslint:disable */ // required as json properties is not lowerCamelCase -import * as moment from 'moment'; +import { DateTime } from 'luxon'; export enum PatronTransactionStatus { OPEN = 'open', @@ -54,9 +54,9 @@ export class PatronTransaction { */ get_events(): Array { return this.events.sort((e1, e2) => { - const e1_moment = moment(e1.creation_date); - const e2_moment = moment(e2.creation_date); - return e2_moment.diff(e1_moment); + const e1_date = DateTime.fromISO(e1.creation_date); + const e2_date = DateTime.fromISO(e2.creation_date); + return e2_date.diff(e1_date); }); } } diff --git a/projects/admin/src/app/record/brief-view/loans-brief-view/loans-brief-view.component.ts b/projects/admin/src/app/record/brief-view/loans-brief-view/loans-brief-view.component.ts index d30070362..bc8f7a5c3 100644 --- a/projects/admin/src/app/record/brief-view/loans-brief-view/loans-brief-view.component.ts +++ b/projects/admin/src/app/record/brief-view/loans-brief-view/loans-brief-view.component.ts @@ -18,10 +18,10 @@ import { Component, inject, Input, OnInit } from '@angular/core'; import { ResultItem } from '@rero/ng-core'; import { PermissionsService } from '@rero/shared'; -import moment from 'moment/moment'; +import { DateTime } from 'luxon'; +import { DialogService } from 'primeng/dynamicdialog'; import { LoanState } from '../../../classes/loans'; import { CirculationLogsComponent } from '../../circulation-logs/circulation-logs.component'; -import { DialogService, DynamicDialogRef } from 'primeng/dynamicdialog'; @Component({ selector: 'admin-loans-brief-view', @@ -65,9 +65,10 @@ export class LoansBriefViewComponent implements ResultItem, OnInit { // State bullet color this._getBadgeStyle(); // Is request is expired + this.record.metadata.request_expire_date = "2024-10-28T08:58:59.979434+00:00"; if ('request_expire_date' in this.record.metadata) { - const requestExpireDate = moment(this.record.metadata.request_expire_date); - this.isRequestExpired = moment().isSameOrAfter(requestExpireDate); + const requestExpireDate = DateTime.fromISO(this.record.metadata.request_expire_date); + this.isRequestExpired = DateTime.now() >= requestExpireDate; } } diff --git a/projects/admin/src/app/record/circulation-logs/circulation-logs.component.html b/projects/admin/src/app/record/circulation-logs/circulation-logs.component.html index 1f6ba2d7e..090a480b3 100644 --- a/projects/admin/src/app/record/circulation-logs/circulation-logs.component.html +++ b/projects/admin/src/app/record/circulation-logs/circulation-logs.component.html @@ -45,7 +45,7 @@ @@ -54,7 +54,7 @@ 0) { dataException.times = data.times; diff --git a/projects/admin/src/app/record/detail-view/document-detail-view/holding/holding-item-temporary-item-type/holding-item-temporary-item-type.component.ts b/projects/admin/src/app/record/detail-view/document-detail-view/holding/holding-item-temporary-item-type/holding-item-temporary-item-type.component.ts index 51d07f1ce..464456e16 100644 --- a/projects/admin/src/app/record/detail-view/document-detail-view/holding/holding-item-temporary-item-type/holding-item-temporary-item-type.component.ts +++ b/projects/admin/src/app/record/detail-view/document-detail-view/holding/holding-item-temporary-item-type/holding-item-temporary-item-type.component.ts @@ -16,7 +16,7 @@ */ import { Component, Input } from '@angular/core'; -import moment from 'moment'; +import { DateTime } from 'luxon'; @Component({ selector: 'admin-holding-item-temporary-item-type', @@ -49,7 +49,7 @@ export class HoldingItemTemporaryItemTypeComponent { hasTemporaryItemType(): boolean { if ('temporary_item_type' in this.record.metadata) { const endDateValue = this.record.metadata.temporary_item_type.end_date || undefined; - return !(endDateValue && moment(endDateValue).isBefore(moment())); + return !(endDateValue && DateTime.fromISO(endDateValue) < DateTime.now()); } return false; } 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 45a3f25e4..e9ea6b3fa 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 @@ -21,8 +21,8 @@ import { IssueService } from '@app/admin/service/issue.service'; import { RecordPermissionService } from '@app/admin/service/record-permission.service'; import { RecordService } from '@rero/ng-core'; import { DetailRecord } from '@rero/ng-core/lib/record/detail/view/detail-record'; -import { IPermissions, IssueItemStatus, PERMISSIONS, PERMISSION_OPERATOR, UserService } from '@rero/shared'; -import moment from 'moment'; +import { IPermissions, IssueItemStatus, PERMISSION_OPERATOR, PERMISSIONS, UserService } from '@rero/shared'; +import { DateTime } from 'luxon'; import { DynamicDialogRef } from 'primeng/dynamicdialog'; import { Observable, Subscription } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; @@ -154,7 +154,7 @@ export class ItemDetailViewComponent implements DetailRecord, OnInit, OnDestroy hasTemporaryItemType(): boolean { if ('temporary_item_type' in this.record.metadata) { const endDateValue = this.record.metadata.temporary_item_type.end_date || undefined; - return !(endDateValue && moment(endDateValue).isBefore(moment())); + return !(endDateValue && DateTime.fromISO(endDateValue) < DateTime.now()); } return false; } diff --git a/projects/admin/src/app/utils/validators.ts b/projects/admin/src/app/utils/validators.ts index a3bee6283..4399b42f1 100644 --- a/projects/admin/src/app/utils/validators.ts +++ b/projects/admin/src/app/utils/validators.ts @@ -1,6 +1,6 @@ /* * RERO ILS UI - * Copyright (C) 2020 RERO + * Copyright (C) 2020-2024 RERO * Copyright (C) 2020 UCLouvain * * This program is free software: you can redistribute it and/or modify @@ -17,13 +17,13 @@ */ import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms'; -import moment from 'moment'; +import { DateTime } from 'luxon'; /** Custom date validators */ export class DateValidators { /** Date format to check */ - static FORMAT_DATE = 'YYYY-MM-DD'; + static DATE_FORMAT = 'yyyy-LL-dd'; /** * Allow to check if a date is valid and older than a specified date @@ -35,18 +35,20 @@ export class DateValidators { if (control.value == null) { return null; } - const controlMoment = moment(control.value, DateValidators.FORMAT_DATE); - if (!controlMoment.isValid()) { + + const date = DateTime.fromJSDate(control.value); + console.log(date, date.isValid); + if (!date.isValid) { return null; } const validationDate = minDate.setHours(0, 0, 0, 0); - const controlDate = controlMoment.toDate().setHours(0, 0, 0, 0); - return controlDate >= validationDate + date.set({ hours: 0, minutes: 0, seconds: 0, milliseconds: 0}); + return date >= validationDate ? null : { 'minimum-date': { - 'date-minimum': moment(validationDate).format(DateValidators.FORMAT_DATE), - actual: controlMoment.format(DateValidators.FORMAT_DATE) + 'date-minimum': DateTime.fromISO(validationDate).toFormat(dateFormat), + actual: date.toFormat(dateFormat) } }; }; diff --git a/projects/public-search/src/app/api/operation-logs-api.service.ts b/projects/public-search/src/app/api/operation-logs-api.service.ts index 16fdac4be..3a7a9c4f8 100644 --- a/projects/public-search/src/app/api/operation-logs-api.service.ts +++ b/projects/public-search/src/app/api/operation-logs-api.service.ts @@ -18,7 +18,7 @@ import { inject, Injectable } from '@angular/core'; import { Error, Record, RecordService } from '@rero/ng-core'; import { BaseApi } from '@rero/shared'; -import moment from 'moment'; +import { DateTime } from 'luxon'; import { Observable } from 'rxjs'; @Injectable({ @@ -40,7 +40,7 @@ export class OperationLogsApiService extends BaseApi { patronPid: string, page: number, itemsPerPage: number = 10 ): Observable { - const date = moment().subtract(6, 'months').utc().format('YYYY-MM-DDTHH:mm:ss'); + const date = DateTime.now().minus({ months: 6 }).toISO(); const query = `record.type:loan AND loan.patron.pid:${patronPid} AND loan.trigger:checkin AND date:[${date} TO *]`; return this.recordService.getRecords( 'operation_logs', query, page, itemsPerPage, diff --git a/projects/public-search/src/app/patron-profile/patron-profile-loans/patron-profile-loan/patron-profile-loan.component.ts b/projects/public-search/src/app/patron-profile/patron-profile-loans/patron-profile-loan/patron-profile-loan.component.ts index 5036cc7ef..40d24efb4 100644 --- a/projects/public-search/src/app/patron-profile/patron-profile-loans/patron-profile-loan/patron-profile-loan.component.ts +++ b/projects/public-search/src/app/patron-profile/patron-profile-loans/patron-profile-loan/patron-profile-loan.component.ts @@ -19,7 +19,7 @@ import { LoanOverduePreview } from '@app/admin/classes/loans'; import { TranslateService } from '@ngx-translate/core'; import { CONFIG } from '@rero/ng-core'; import { IOrganisation } from '@rero/shared'; -import moment from 'moment'; +import { DateTime } from 'luxon'; import { MessageService } from 'primeng/api'; import { finalize } from 'rxjs/operators'; import { CanExtend, LoanApiService } from '../../../api/loan-api.service'; @@ -74,7 +74,7 @@ export class PatronProfileLoanComponent implements OnInit { get isDueSoon(): boolean { return (this.record.metadata.is_late) ? false - : new moment(this.record.metadata.due_soon_date) <= moment(); + : DateTime.fromISO(this.record.metadata.due_soon_date) <= DateTime.now(); } /** OnInit hook */