1var OJ = OJ || {}; 2 3OJ.Endpoints = { 4 'live': 'https://api.onejourney.travel', 5 'staging': 'https://api.release-api.testonejourney.com' 6} 7 8OJ.DataAdapter = function(options, id) { 9 this.endpoint = apiOptions.debug == '1' ? OJ.Endpoints['live'] : OJ.Endpoints['live'] 10 this.request = null 11 this.configure(id) 12} 13 14OJ.DataAdapter.prototype.configure = function(hotelID) { 15 if(!hotelID) return false 16 this.setHotelID(hotelID) 17} 18 19OJ.DataAdapter.prototype.setHotelID = function(hotelID){ 20 this.hotelID = hotelID 21} 22 23OJ.DataAdapter.prototype.formatPrice = function(price){ 24 if(!price) return ''; 25 26 let amount = Math.ceil(price.amount / 100) 27 28 let options = { 29 style: 'currency', 30 currency: price.currency_code, 31 minimumFractionDigits: 0, 32 maximumFractionDigits: 0, 33 } 34 35 return new Intl.NumberFormat('en-GB', options).format(amount); 36} 37 38OJ.DataAdapter.prototype.imgixImage = function(image, h = 100, w = 100) { 39 let extension = image['url'].split('.').pop() 40 return `https://products-live.imgix.net/${image['external_key']}.${extension}?auto=format&fit=crop&crop=entropy&h=${h}&w=${w}&q=75` 41} 42 43OJ.DataAdapter.prototype.availabilityRequest = function(query) { 44 let url = this.endpoint + "/" + this.hotelID + "/rooms/calendar/" + query['adults'] + "/" + query['fromDate'] + "/" + query['toDate'] + "/availability?infants=" + query['infants'] + (query['rate'] ? "&rate-code=" + query['rate'] : "") + (query['room'] ? "&room-code=" + query['room'] : "") 45 return $.get(url) 46} 47 48OJ.DataAdapter.prototype.getAvailability = function(query, callback) { 49 let apiCall = this.availabilityRequest(query) 50 51 this.request = apiCall.done((response) => { 52 callback(this.mapAvailabilityData(response)) 53 }).fail((response) => { 54 callback(response.responseJSON) 55 }) 56} 57 58OJ.DataAdapter.prototype.mapAvailabilityData = function(response) { 59 let json = {} 60 61 response.map((day) => { 62 json[day.date] = { 63 'type': day.type, 64 'minimum_stay': day.minimum_stay, 65 'maximum_stay': day.maximum_stay, 66 'price': this.formatPrice(day.price) 67 } 68 }) 69 70 return json 71} 72 73OJ.DataAdapter.prototype.roomAvailabilityRequest = function(query) { 74 if(!Object.values(query).every((value) => value != undefined)) return false 75 let url = this.endpoint + "/" + this.hotelID + "/rooms?from-date=" + query['fromDate'] + "&to-date=" + query['toDate'] + "&adults=" + query['adults'] + "&infants=" + query['infants'] 76 return $.get(url) 77} 78 79OJ.DataAdapter.prototype.getAvailableRooms = function(query, callback) { 80 // returns all rooms that are available between certain dates 81 82 let apiCall = this.roomAvailabilityRequest(query) 83 84 this.request = apiCall.done((response) => { 85 callback(this.mapAvailableRoomsData(response)) 86 }).fail((response) => { 87 callback(response.responseJSON) 88 }) 89 90 return this.request 91} 92 93OJ.DataAdapter.prototype.mapAvailableRoomsData = function(response) { 94 return response 95} 96 97OJ.DataAdapter.prototype.roomsRequest = function(roomID) { 98 let url = this.endpoint + "/" + this.hotelID + "/rooms/" + (roomID ? roomID + "/" : "") + "details" 99 return $.get(url) 100} 101 102OJ.DataAdapter.prototype.getAllRooms = function(query, callback) { 103 // returns the details for all rooms 104 105 let apiCall = this.roomsRequest(query) 106 107 this.request = apiCall.done((response) => { 108 callback(this.mapRoomsData(response)) 109 }).fail((response) => { 110 callback(response.responseJSON) 111 }) 112} 113 114OJ.DataAdapter.prototype.mapRoomsData = function(response) { 115 return response 116} 117 118OJ.DataAdapter.prototype.getRoomsDetails = function(query, callback) { 119 let rooms = this.roomsRequest(query['roomID']) 120 let availableRooms = this.roomAvailabilityRequest(query) 121 122 $.when(rooms, availableRooms).done((rooms, availableRooms) => { 123 callback(this.mapRoomDetails(rooms, availableRooms)) 124 }).fail((roomsFail, availableRoomsFail) => { 125 let roomsResponseJSON = roomsFail.responseJSON || {} 126 let availableRoomsFailResponseJSON = availableRoomsFail.responseJSON || {} 127 callback({...roomsResponseJSON, ...availableRoomsFailResponseJSON}) 128 }) 129} 130 131OJ.DataAdapter.prototype.mapRoomDetails = function(rooms, availableRooms) { 132 if(!rooms[0] && !availableRooms) return [] 133 134 let allRooms = rooms[0].data || [rooms[0]] 135 let availableRoomsData = availableRooms ? availableRooms[0].data : [] 136 let orderByPrice = (a, b) => { 137 if(a['price_per_night'] && b['price_per_night']) { 138 return a['price_per_night']['raw'] > b['price_per_night']['raw'] ? 1 : -1 139 } else { 140 return !a['available'] ? 1 : -1 141 } 142 } 143 144 return allRooms.map((room) => { 145 let roomData = availableRoomsData.filter((available) => available.id == room.room_id)[0] 146 let available = roomData ? true : false 147 148 let roomObject = { 149 'id': room.room_id, 150 'title': room.title, 151 'image': room.image_url, 152 'available': available, 153 'max_occupancy': room.max_occupancy 154 } 155 156 if(available) { 157 Object.assign(roomObject, { 158 'price_per_night': { 159 raw: roomData.price_per_night.amount, 160 formatted: this.formatPrice(roomData.price_per_night), 161 }, 162 'price_per_stay': { 163 raw: roomData.price_per_night.amount, 164 formatted: this.formatPrice(roomData.price_per_stay), 165 }, 166 'quantity': roomData.quantity, 167 'display_urgency_messaging': roomData.display_urgency_messaging, 168 }) 169 } 170 171 return roomObject 172 }).sort(orderByPrice) 173} 174 175 176OJ.DataAdapter.prototype.getRestaurants = function(callback) { 177 let url = this.endpoint + "/" + this.hotelID + "/tables/restaurants/en" 178 179 this.request = $.get(url).done((response) => { 180 callback(this.mapRestaurantData(response)) 181 }).fail((response) => { 182 callback(response.responseJSON) 183 }) 184} 185 186OJ.DataAdapter.prototype.mapRestaurantData = function(restaurants) { 187 return restaurants.map((restaurant) => { 188 return { 189 value: restaurant.name_display, 190 key: restaurant.name, 191 image: restaurant.config?.image_gallery.length ? this.imgixImage(restaurant.config.image_gallery[0]) : '' 192 } 193 }) 194} 195 196OJ.DataAdapter.prototype.getCategories = function(type, callback) { 197 let url = this.endpoint + "/" + this.hotelID + "/categories" 198 199 this.request = $.get(url).done((response) => { 200 this.categories = response.data 201 callback(this.mapCategoriesData(this.categories, type)) 202 }).fail((response) => { 203 callback(response.responseJSON) 204 }) 205} 206 207OJ.DataAdapter.prototype.mapCategoriesData = function(categories, typeFilter) { 208 return categories.map((category) => { 209 let types = ["products","treatments","spa_days","spa_packages","spa_classes","vouchers","events"] 210 let typeMatch = true 211 212 if(typeFilter) { 213 typeMatch = typeFilter instanceof Array ? Object.keys(category).filter((value) => { 214 return typeFilter.includes(value.replace('has_', '')) && category[value] == true 215 }).length > 0 : category[`has_${typeFilter}`] 216 } 217 218 if(category.is_private || !typeMatch) return false 219 220 return { 221 key: category['id'], 222 value: category['name'], 223 has: types.filter((type) => category[`has_${type}`]), 224 image: category['image'] ? this.imgixImage(category['image']) : '' 225 } 226 }).filter((el) => el !== false) 227} 228 229OJ.DataAdapter.prototype.getSpaPackages = function(type, callback) { 230 let url = this.endpoint + "/" + this.hotelID + "/spa-packages?per-page=0" 231 232 this.request = $.get(url).done((response) => { 233 callback(this.mapSpaPackagesData(response.data, type)) 234 }).fail((response) => { 235 callback(response.responseJSON) 236 }) 237} 238 239OJ.DataAdapter.prototype.mapSpaPackagesData = function(packages) { 240 return packages.sort((a, b) => a.display_order > b.display_order ? 1 : -1).map((package) => { 241 return { 242 key: package.id, 243 value: package.name, 244 image: package.image ? this.imgixImage(package.image) : '', 245 price: this.formatPrice(package.price), 246 duration: package.duration_text, 247 } 248 }) 249} 250 251OJ.DataAdapter.prototype.getSpaTreatments = function(type, callback) { 252 let url = this.endpoint + "/" + this.hotelID + "/spa-treatments?per-page=0" 253 254 this.request = $.get(url).done((response) => { 255 callback(this.mapSpaTreatmentsData(response.data, type)) 256 }).fail((response) => { 257 callback(response.responseJSON) 258 }) 259} 260 261OJ.DataAdapter.prototype.mapSpaTreatmentsData = function(treatments) { 262 return treatments.sort((a, b) => a.display_order > b.display_order ? 1 : -1).map((treatment) => { 263 return {
264 key: treatment.id, 265 value: treatment.name, 266 image: treatment.image ? this.imgixImage(treatment.image) : '', 267 price: this.formatPrice(treatment.price), 268 duration: treatment.duration, 269 categories: treatment.categories 270 } 271 }) 272} 273 274OJ.DataAdapter.prototype.getSpaTreatment = function(id, callback) { 275 let url = this.endpoint + "/" + this.hotelID + "/spa-treatments/" + id 276 277 this.request = $.get(url).done((response) => { 278 callback(this.mapSingleSpaTreatmentData(response)) 279 }).fail((response) => { 280 callback(response.responseJSON) 281 }) 282} 283 284OJ.DataAdapter.prototype.mapSingleSpaTreatmentData = function(treatment) { 285 let response = Object.assign({}, treatment) 286 response.price = this.formatPrice(treatment.price) 287 response.image = treatment.image ? this.imgixImage(treatment.image) : '' 288 return response 289} 290 291OJ.DataAdapter.prototype.cancelExistingRequest = function() { 292 if(this.request) this.request.abort() 293}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.