/***
* src/js/ice.availability.plugin.js
*/
/**
* @module Availability Plugin
*/
/**
* @class AvailabilityPlugin
*/
define(['_', 'promise', './util/util', './data/SummaryData', './data/PlaceAvailabilityData', './templates/templateSettings', './data/urlBuilder', './util/validation', './registerCoreEndpoints'],
function (_, Promise, util, SummaryData, PlaceData, settings, UrlBuilder, Validation, registerCoreEndpoints) {
var DEFAULT_SUMMARY_INTERVAL = 75 * 1000;
var DEFAULT_PLACE_INTERVAL = 30 * 1000;
var setCore = function setCore(plugin, core) {
if (!core) {
return new TypeError('availability requires a valid core instance');
}
plugin.core = core;
};
var parseOffers = function (plugin, offers) {
var index = 0,
length = offers.length,
offer;
while (index < length) {
offer = offers[index];
plugin.offers[offer.offerId] = offer;
index++;
}
};
var setOffers = function (plugin, eventOffers) {
var embedded = eventOffers && eventOffers._embedded;
if (embedded) {
var offers = embedded && embedded.item;
if (offers) {
parseOffers(plugin, offers)
}
}
};
var addOffersToShape = function (shapes, offerIds, segment, plugin) {
var shapesLength = shapes.length,
shapeIndex;
var offerIdsLength = offerIds.length,
offerIdsIndex;
for (shapeIndex = 0; shapeIndex < shapesLength; shapeIndex++) {
var shapeId = shapes[shapeIndex];
if (segment.id === shapeId) {
for (offerIdsIndex = 0; offerIdsIndex < offerIdsLength; offerIdsIndex++) {
var offerId = offerIds[offerIdsIndex];
segment.offers.push(plugin.offers[offerId]);
}
}
}
};
var addOffersToSegments = function (facets, segment, plugin) {
var facetsIndex,
facetsLength = facets.length;
for (facetsIndex = 0; facetsIndex < facetsLength; facetsIndex++) {
var facet = facets[facetsIndex];
var shapes = facet.shapes;
var offerIds = facet.offers;
addOffersToShape(shapes, offerIds, segment, plugin);
}
};
var setSegmentsOffers = function (plugin, segmentsOffers) {
var facets = segmentsOffers.facets;
var segments = plugin.core.data.segmentsById;
for (var i = 0; i < Object.keys(segments).length; i++) {
var segmentId = Object.keys(segments)[i];
var segment = segments[segmentId];
addOffersToSegments(facets, segment, plugin);
}
};
var setAdaData = function setAdaData(plugin, adaData) {
plugin._adaData = adaData.facets;
window.adaData = plugin._adaData;
};
var setAdaSeatsBySegmentId = function (segmentIds, adaData, places) {
var segmentIndex, adaIndex, placeIndex, adaDataLength;
for (segmentIndex = 0; segmentIndex < segmentIds.length; segmentIndex++) {
var segmentId = segmentIds[segmentIndex];
adaDataLength = adaData ? adaData.length : 0;
for (adaIndex = adaDataLength - 1; adaIndex >= 0; adaIndex--) {
var shape = adaData[adaIndex].shapes[0];
if (segmentId == shape) {
var adaSegment = adaData[adaIndex];
var adaPlaces = adaSegment.places;
for (placeIndex = 0; placeIndex < adaPlaces.length; placeIndex++) {
var place = places[adaPlaces[placeIndex]];
place.attributes = adaSegment.attributes;
place.accessibility = adaSegment.accessibility;
place.ada = _.includes(place.attributes, 'accessible');
}
adaData.splice(adaIndex, 1);
}
}
}
};
/**
* @class AvailabilityPlugin
* @param {Core} core A reference to core object
* @param {Object} options A list of options to set
* @param {String|URL} options.service the url to the ismds server that will return availability data
* @param {String} options.apiKey the API key is needed for authentication by the ISMDS service
* @param {String} options.apiSecret the API secret is also needed for authentication by the ISMDS service
* @param {Integer} [options.placeUpdateInterval=30000] the amount of milliseconds that have to pass before the place availability will update
* @param {Integer} [options.summaryUpdateInterval=75000] the amount of milliseconds that have to pass before the summary will update
* @param {Boolean} [options.platinumEnabled] Indicates if platinum data is to be fetched
* @param {Boolean} [options.resaleEnabled] Indicates if resale data is to be fetched
* @param {Array} [options.ranges] An array of objects with the keys range, and color
* @constructor
* @example
* var ismdsOptions= {
* service: 'https://services.ticketmaster.com/api/ismds',
* apiKey: 'aj6sxy6vhtv7bujsnvgejsblcifgfd',
* apiSecret:'sc2ruf344746p4symm3lunsbbqfs',
* summaryUpdateInterval: 10000,
* placeUpdateInterval: 5000,
* platinumEnabled: true;
* resaleEnabled: true,
* ranges:[{range: '0',color: '999999'}, {range: '0.25', color: '000000'}, {range: '0.25', color: '91c9ea'}, {range: '0.75', color: '1099de'}, {range: '1', color: '004878'}]
* };
* ICE.ISMDSPlugin.create(ice, ismdsOptions);
*/
var ISMDSPlugin = function ISMDSPlugin(core, options) {
options = options || {};
var self = this;
/**
* Instance of core
* @property core
* @type {CORE}
*/
setCore(this, core);
/**
* Sets the link to the availability server
* @property service
* @type {String}
*/
this.service = Validation.validateServiceUrl(options.service);
/**
* Indicates whether or not we get platinum data
* @property platinumEnabled
* @type {Boolean}
*/
this.platinumEnabled = Boolean(options.platinumEnabled);
/**
* Indicates whether or not we get resale data
* @property resaleEnabled
* @type {Boolean}
*/
this.resaleEnabled = Boolean(options.resaleEnabled);
/**
* Sets the delay for fetching availability data for segments
* @property summaryUpdateInterval
* @default 75000
* @type {Integer} Milliseconds
*/
this.summaryUpdateInterval = Validation.validateIntervalRange(options.summaryUpdateInterval || DEFAULT_SUMMARY_INTERVAL, 10000, 500000);
/**
* Sets the delay for fetching availability data for places
* @property placeUpdateInterval
* @default 30000
* @type {Integer} Milliseconds
*/
this.placeUpdateInterval = Validation.validateIntervalRange(options.placeUpdateInterval || DEFAULT_PLACE_INTERVAL, 5000, 500000);
/**
* The API Key is needed for authentication by the ISMDS service
* @property apiKey
* @private
* @type {String}
*/
this._apiKey = options.apiKey;
/**
* The API secret is also needed for authentication by the ISMDS service
* @property apiSecret
* @private
* @type {String}
*/
this._apiSecret = options.apiSecret;
this.offers = {};
this._placeOfferData = {};
this._adaData = null;
SummaryData.init(core, options.ranges);
PlaceData.init(core);
core.on('update-visible-sections', function (results) {
var segmentIds = results.newlyVisibleSections;
var adaData = self._adaData;
if (segmentIds.length) {
PlaceData.getPlaceData(self, segmentIds, self.placeUpdateInterval);
}
setAdaSeatsBySegmentId(segmentIds, adaData, core.data.placesById);
});
core.on('draw-complete', function () {
self.urlBuilder = new UrlBuilder(self.service, this.data.config, self._apiKey, self._apiSecret);
SummaryData.getSummaryData(self, self.summaryUpdateInterval);
var promises = [
self.urlBuilder.getOffers(),
self.urlBuilder.getSegmentsOffers(),
self.urlBuilder.getAdaData()
];
Promise.all(promises)
.then(function (responses) {
var offers = responses[0],
segmentsOffers = responses[1],
adaData = responses[2];
setOffers(self, offers);
setSegmentsOffers(self, segmentsOffers);
setAdaData(self, adaData);
});
var renderedSections = this.map.renderedSections;
PlaceData.fetchPlaceData(self, util.pluck(renderedSections, 'id'), self.placeUpdateInterval);
});
registerCoreEndpoints(this);
};
return ISMDSPlugin;
});