import * as _ from 'lodash'; import * as moment from 'moment'; export interface CalEvent { id: string; calendarId: string; tenantId: string; storeId: string; userId: string; title: string; start: moment.Moment; end: moment.Moment; notes: string; confirmedStatus: boolean; booking: Booking; } export interface Booking{ enabled: boolean; seated: boolean; touchpointId: string; customers: string[]; customersNum: number; phone: number; } export class Calendar { static createDummyCalendar(): Calendar { let dummyCalendar = new Calendar( '__DUMMY__' , '__DUMMY__' , '__DUMMY__' , '__DUMMY__' , '__DUMMY__' , moment('1970-01-01T00:00:00') , [Calendar.createDummyEvent()] ); return dummyCalendar; } static createDummyEvent(): CalEvent { let dummyCalEvent: CalEvent = { id: '__DUMMY__' , calendarId: '__DUMMY__' , tenantId: '__DUMMY__' , storeId: '__DUMMY__' , userId: '__DUMMY__' , title: '__DUMMY__' , start: moment('1970-01-01T00:00:00') , end: moment('1970-01-01T00:00:00') , notes: '__DUMMY__' , confirmedStatus: false , booking: { enabled : false , seated : false , touchpointId : '__DUMMY__' , customers : null , customersNum : null , phone : null } }; return dummyCalEvent; } static fromJson(obj: any): Calendar { let id: string = (obj.id) ? obj.id : '__FALLBACK__'; let _tenantId: string = (obj.tenantId) ? obj.tenantId : '__FALLBACK__'; let _storeId: string = (obj.storeId) ? obj.storeId : '__FALLBACK__'; let _userId: string = (obj.userId) ? obj.userId : '__FALLBACK__'; let _title: string = (obj.title) ? obj.title : '__FALLBACK__'; let _createdOn: moment.Moment = (obj.created) ? moment(obj.created) : moment('1970-01-01T00:00:00'); let _events: CalEvent[] = []; if (obj.events) { _(obj.events).forEach( (calEvent: any) => { _events.push(this.eventFromJson(calEvent)); }); } // TODO return error and handle it visually if api response not compatible return new Calendar(id, _tenantId, _storeId, _userId, _title, _createdOn, _events); } static bookingFromJson(obj: any): Booking{ let _touchpointId: string = (obj.touchpointId) ? obj.touchpointId : '__FALLBACK__'; let _customers: string[] = (obj.customers) ? obj.customers : ['Guest']; let _enabled: boolean = (obj.enabled) ? obj.enabled : false; let _seated: boolean = (obj.seated) ? obj.seated : false; let _customersNum: number = (obj.customersNum) ? obj.customersNum : 1; let _phone: number = (obj.phone) ? obj.phone : 1337; let newBooking: Booking = { enabled: _enabled , seated: _seated , touchpointId: _touchpointId , customers: _customers , customersNum: _customersNum , phone: _phone } return newBooking; } static eventFromJson(obj: any): CalEvent { // TODO make CalEvent a class and add this function as fromJson into it let _eventId: string = (obj.id) ? obj.id : '__FALLBACK__'; let _calendarId: string = (obj.calendarId) ? obj.calendarId : '__FALLBACK__'; let _tenantId: string = (obj.tenantId) ? obj.tenantId : '__FALLBACK__'; let _storeId: string = (obj.storeId) ? obj.storeId : '__FALLBACK__'; let _userId: string = (obj.userId) ? obj.userId : '__FALLBACK__'; let _title: string = (obj.title) ? obj.title : '__FALLBACK__'; let _start: moment.Moment = (obj.startDate) ? moment(obj.startDate) : moment('1970-01-01T00:00:00'); let _end: moment.Moment = (obj.endDate) ? moment(obj.endDate) : moment('1970-01-01T00:00:00'); let _notes: string = (obj.notes) ? obj.notes : '__FALLBACK__'; let _confirmed: boolean = (obj.confirmed) ? obj.confirmed : false; let _booking: Booking = (obj.booking) ? this.bookingFromJson(obj.booking) : { enabled: false , seated: false , touchpointId: null , customers: null , customersNum: null , phone: null }; // TODO return error and handle it visually if api response not compatible let newCalEvent: CalEvent = { id: _eventId , calendarId: _calendarId , tenantId: _tenantId , storeId: _storeId , userId: _userId , title: _title , start: _start , end: _end , notes: _notes , confirmedStatus: _confirmed , booking: _booking }; return newCalEvent; } static updateOrPushCalendar(calendarToUpdate: Calendar, calendars: Calendar[]) { let indexOfItemToUpdate = _.findIndex(calendars, (cal: Calendar) => { return cal.getCalendarId() === calendarToUpdate.getCalendarId(); }); if (indexOfItemToUpdate !== -1) { calendars[indexOfItemToUpdate] = calendarToUpdate; } else if (indexOfItemToUpdate === -1) { calendars.push(calendarToUpdate); // Display warning only if it isn't the case of initialising our calendars array if ( !(calendars.length === 1) ) { console.warn('Warning: Former version of updated calendar was not found in local cache, but cache was synced anyway.'); } } } static deleteCalendar(calendarToDelete: Calendar, calendars: Calendar[]) { let indexOfItemToDelete = _.findIndex(calendars, (cal: Calendar) => { return cal.getCalendarId() === calendarToDelete.getCalendarId(); }); if (indexOfItemToDelete !== -1) { calendars.splice(indexOfItemToDelete, 1); // If the deleted calendar was the last one, make sure it is at least populated with a dummy if (calendars.length === 0) { calendars.push(Calendar.createDummyCalendar()); } } else if (indexOfItemToDelete === -1) { console.warn('Warning: Former version of deleted calendar not found in local cache.'); } } static updateOrPushEvent(eventToUpdate: CalEvent, events: CalEvent[]) { // If we are adding the first event ever then clear the cache of Dummy objects first if (events[0].id === '__DUMMY__') { events.splice(0); } let deletedEvents: CalEvent[] = _.remove(events, (ev: CalEvent) => { return ev.id === eventToUpdate.id; }); events.push(eventToUpdate); if (deletedEvents.length === 0) { // _.remove() returns an array of all found and deleted items` console.warn('Warning: Former version of updated event was not found in local cache, but cache was synced anyway.'); } } static deleteEvent(eventToDelete: CalEvent, events: CalEvent[]) { let deletedEvents: CalEvent[] = _.remove(events, (e: CalEvent) => { return e.id === eventToDelete.id; }); if (deletedEvents.length <= 0) { // _.remove() returns an array of all found and deleted items console.warn(`Warning: Deleting event from local cache failed because no former version of the deleted event was found.`); } } constructor( public calendarId: string , public tenantId: string // Identifier of the brand to which this calendar belongs , public storeId: string // Identifier of the store wherein this calendar applies , public userId: string // Identifier of the Omnixell user that created the calendar , public title: string , public createdOn: moment.Moment , public calEvents: CalEvent[] = [] ) {} findEvent(eventId: string): CalEvent { return _.find(this.getCalEvents(), (e: CalEvent) => { return e.id === eventId; }); } getCalendarId () { return this.calendarId; } getTenantId () { return this.tenantId; } getStoreId () { return this.storeId; } getUserId () { return this.userId; } getTitle () { return this.title; } getCreatedOn () { return this.createdOn; } getCalEvents () { return this.calEvents; } }