LP1816475: make multiday grid work
authorJane Sandberg <sandbej@linnbenton.edu>
Sun, 7 Apr 2019 02:05:17 +0000 (19:05 -0700)
committerJane Sandberg <sandbej@linnbenton.edu>
Wed, 17 Apr 2019 20:41:53 +0000 (13:41 -0700)
Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>
Open-ILS/src/eg2/src/app/staff/booking/create-reservation.component.html
Open-ILS/src/eg2/src/app/staff/booking/create-reservation.component.ts

index 873a41f..41b7bfa 100644 (file)
@@ -31,8 +31,8 @@
         <button *ngIf="!multiday" class="btn btn-outline-primary" ngbDropdownToggle><span class="material-icons">event</span><span i18n>Single day reservation</span></button>
         <button *ngIf="multiday" class="btn btn-outline-primary" ngbDropdownToggle><span class="material-icons">date_range</span><span i18n>Multiple day reservation</span></button>
         <div ngbDropdownMenu id="ideal-reservation-type">
-          <button (click)="multiday = false" class="btn btn-outline-primary" ngbDropdownItem><span class="material-icons">event</span><span i18n>Single day reservation</span></button>
-          <button (click)="multiday = true" class="btn btn-outline-primary" ngbDropdownItem><span class="material-icons">date_range</span><span i18n>Multiple day reservation</span></button>
+          <button (click)="handleSingleDayReservation()" class="btn btn-outline-primary" ngbDropdownItem><span class="material-icons">event</span><span i18n>Single day reservation</span></button>
+          <button (click)="handleMultiDayReservation()" class="btn btn-outline-primary" ngbDropdownItem><span class="material-icons">date_range</span><span i18n>Multiple day reservation</span></button>
         </div>
       </div>
     </div>
@@ -42,8 +42,8 @@
       <div class="input-group-prepend">
         <label class="input-group-text" for="ideal-reservation-date" i18n>Reservation date</label>
       </div>
-      <eg-date-select *ngIf="!multiday" #dateLimiter domId="ideal-reservation-date" (onChangeAsDate)="handleDateChange($event)" [initialDate]="today"></eg-date-select>
-      <eg-daterange-select *ngIf="multiday" #dateRangeLimiter></eg-daterange-select>
+      <eg-date-select *ngIf="!multiday" #dateLimiter domId="ideal-reservation-date" (onChangeAsDate)="handleDateChange($event)" [initialDate]="idealDate"></eg-date-select>
+      <eg-daterange-select *ngIf="multiday" #dateRangeLimiter (onChange)="fetchData()"></eg-daterange-select>
     </div>
   </div>
   <div class="col">
index d454ea1..b2bb56a 100644 (file)
@@ -1,7 +1,7 @@
 import {Component, Input, OnInit, AfterViewInit, QueryList, ViewChildren, ViewChild} from '@angular/core';
 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
 import {single} from 'rxjs/operators';
-import {NgbTimeStruct} from '@ng-bootstrap/ng-bootstrap';
+import {NgbDateStruct, NgbTimeStruct} from '@ng-bootstrap/ng-bootstrap';
 import {AuthService} from '@eg/core/auth.service';
 import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
 import {DateSelectComponent} from '@eg/share/date-select/date-select.component';
@@ -40,8 +40,6 @@ export class CreateReservationComponent implements OnInit, AfterViewInit {
 
     startOfDay: NgbTimeStruct = {hour: 9, minute: 0, second: 0};
     endOfDay: NgbTimeStruct = {hour: 17, minute: 0, second: 0};
-    startTime: Moment;
-    endTime: Moment;
     granularity: 15 | 30 | 60 | 1440 = 30; // 1440 minutes = 24 hours
 
     scheduleSource: GridDataSource = new GridDataSource();
@@ -61,7 +59,7 @@ export class CreateReservationComponent implements OnInit, AfterViewInit {
     @ViewChild('newDialog') newDialog: FmRecordEditorComponent;
     @ViewChild('rt') rt: ResourceTypeComboboxComponent;
 
-    today = new Date();
+    idealDate = new Date();
 
     constructor(
         private auth: AuthService,
@@ -138,17 +136,21 @@ export class CreateReservationComponent implements OnInit, AfterViewInit {
                 this.granularity = 1440;
             } else {
                 this.store.getItem('eg.booking.create.granularity').then(granularity => {
-                    if (granularity != null) { this.granularity = granularity; }
+                    if (granularity) { 
+                        this.granularity = granularity;
+                    } else {
+                        this.granularity = 30;
+                    }
                 });
             }
-            this.fetchData();
         };
 
         this.handleDateChange = ($event: Date) => {
+            this.idealDate = $event;
             this.pcrud.retrieve('aouhoo', this.auth.user().ws_ou())
             .subscribe(hours => {
-                const startArray = hours['dow_' + ($event.getDay() + 6) % 7 + '_open']().split(':');
-                const endArray = hours['dow_' + ($event.getDay() + 6) % 7 + '_close']().split(':');
+                const startArray = hours['dow_' + (this.idealDate.getDay() + 6) % 7 + '_open']().split(':');
+                const endArray = hours['dow_' + (this.idealDate.getDay() + 6) % 7 + '_close']().split(':');
                 this.startOfDay = {
                     hour: ('00' === startArray[0]) ? 9 : +startArray[0],
                     minute: +startArray[1],
@@ -164,16 +166,19 @@ export class CreateReservationComponent implements OnInit, AfterViewInit {
         this.handleMultiDayReservation = () => {
             this.multiday = true;
             this.setGranularity();
+            this.fetchData();
         };
 
         this.handleSingleDayReservation = () => {
             this.multiday = false;
             this.setGranularity();
+            this.handleDateChange(new Date());
         };
 
         this.changeGranularity = ($event) => {
             this.granularity = $event.id;
             this.store.setItem('eg.booking.create.granularity', $event.id);
+            this.fetchData();
         };
 
         this.useCurrentResourceBarcode = () => {
@@ -188,6 +193,7 @@ export class CreateReservationComponent implements OnInit, AfterViewInit {
     ngAfterViewInit() {
         this.dateLimiters.forEach((dl) => dl.initialDate = new Date());
         this.setGranularity();
+        this.fetchData();
     }
 
     showNewDialog(idlThing: IdlObject) {
@@ -221,7 +227,9 @@ export class CreateReservationComponent implements OnInit, AfterViewInit {
 
     fetchData () {
         this.resources = [];
+        let select = {};
         let where = {};
+
        if (this.resourceId) {
             where = {id: this.resourceId};
         } else if (this.resourceTypeId) {
@@ -229,44 +237,70 @@ export class CreateReservationComponent implements OnInit, AfterViewInit {
         } else {
             return;
         }
+
+        if (this.multiday) {
+            this.dateRangeLimiters.forEach((drl) => {
+                select = {'curr_rsrcs': {'end_time': {'>' : Moment.tz([drl.fromDate.year, drl.fromDate.month - 1, drl.fromDate.day], this.format.wsOrgTimezone).startOf('day').toISOString()},
+                    'start_time': { '<': Moment.tz([drl.toDate.year, drl.toDate.month - 1, drl.toDate.day], this.format.wsOrgTimezone).endOf('day').toISOString() }}}
+            });
+        } else {
+            select = {'curr_rsrcs': {'end_time': {'>' : Moment.tz([this.idealDate.getFullYear(), this.idealDate.getMonth(), this.idealDate.getDate()], this.format.wsOrgTimezone).startOf('day').toISOString()},
+                'start_time': { '<': Moment.tz([this.idealDate.getFullYear(), this.idealDate.getMonth(), this.idealDate.getDate()], this.format.wsOrgTimezone).add(1, 'days').endOf('day').toISOString() }}}
+        }
         this.scheduleSource.data = [];
         this.pcrud.search('brsrc', where, {
             order_by: 'barcode ASC',
             flesh: 2,
             flesh_fields: {'brsrc': ['curr_rsrcs'], 'bresv': ['usr']},
-            select: {'curr_rsrcs': {'end_time': {'>' : Moment([], this.format.wsOrgTimezone).startOf('day').toISOString()},
-                'start_time': { '<': Moment([], this.format.wsOrgTimezone).add(1, 'days').endOf('day').toISOString() }}}
+            select: select
         }).subscribe(
             r => {
                 this.resources.push(r);
 
-                this.dateLimiters.forEach((dl) => {
-                    this.startTime = Moment.tz([
-                        dl.current.year,
-                        dl.current.month - 1,
-                        dl.current.day,
-                       this.startOfDay.hour,
-                        this.startOfDay.minute],
-                        this.format.wsOrgTimezone);
-                    this.endTime = Moment.tz([
-                        dl.current.year,
-                        dl.current.month - 1,
-                        dl.current.day,
-                        this.endOfDay.hour,
-                        this.endOfDay.minute],
-                        this.format.wsOrgTimezone);
-                });
-                let currentTime = this.startTime;
-                while (currentTime < this.endTime) {
-                    const existingRow = this.scheduleSource.data.findIndex((row) => row['time'] === currentTime.format('LT')) ;
-                    const idx = (existingRow > -1) ? existingRow : (this.scheduleSource.data.push({'time': currentTime.format('LT')}) - 1);
+                let startTime = Moment();
+                let endTime = Moment();
+                if (this.multiday) {
+                   this.dateRangeLimiters.forEach((drl) => {
+                       startTime = Moment.tz([drl.fromDate.year, drl.fromDate.month - 1, drl.fromDate.day], this.format.wsOrgTimezone).startOf('day');
+                       endTime = Moment.tz([drl.toDate.year, drl.toDate.month - 1, drl.toDate.day], this.format.wsOrgTimezone).endOf('day');
+                   });
+                } else {
+                    this.dateLimiters.forEach((dl) => {
+                        startTime = Moment.tz([
+                            dl.current.year,
+                            dl.current.month - 1,
+                            dl.current.day,
+                            this.startOfDay.hour,
+                            this.startOfDay.minute],
+                            this.format.wsOrgTimezone);
+                        endTime = Moment.tz([
+                            dl.current.year,
+                            dl.current.month - 1,
+                            dl.current.day,
+                            this.endOfDay.hour,
+                            this.endOfDay.minute],
+                            this.format.wsOrgTimezone);
+                    });
+                }
+                let currentTime = startTime;
+                while (currentTime < endTime) {
+                    let idx: number;
+                    let existingRow: number;
+                    if (this.multiday) {
+                        existingRow = this.scheduleSource.data.findIndex((row) => row['time'] === this.format.transform({value: currentTime, datatype: 'timestamp'}));
+                        idx = (existingRow > -1) ? existingRow : (this.scheduleSource.data.push({'time': this.format.transform({value: currentTime, datatype: 'timestamp'})}) - 1);
+                    } else {
+                        existingRow = this.scheduleSource.data.findIndex((row) => row['time'] === currentTime.format('LT')) ;
+                        idx = (existingRow > -1) ? existingRow : (this.scheduleSource.data.push({'time': currentTime.format('LT')}) - 1);
+                    }
                     r.curr_rsrcs().forEach((reservation) => {
-                        if ((Moment(reservation.start_time(), 'Asia/Tokyo') < (currentTime + this.granularity)) && (Moment(reservation.end_time(), 'Asia/Tokyo') > currentTime)) {
+                        if ((Moment(reservation.start_time(), this.format.wsOrgTimezone) < (currentTime.clone().add(this.granularity, 'minutes'))) &&
+                            (Moment(reservation.end_time(), this.format.wsOrgTimezone) > currentTime)) {
                             if (!this.scheduleSource.data[idx][r.barcode()]) { this.scheduleSource.data[idx][r.barcode()] = []; }
                             this.scheduleSource.data[idx][r.barcode()].push({'patronLabel': reservation.usr().usrname(), 'patronId': reservation.usr().id()});
                         }
                     });
-                    currentTime.minute(currentTime.minute() + this.granularity);
+                    currentTime.add(this.granularity, 'minutes');
                 }
             });
     }