API Docs for: 1.7.0
Show:

File: src/js/data/PlaceAvailabilityData.js

/**
 * Created by Chantell.Nichols on 10/8/2015.
 */
define(['_', 'promise', './../util/util'], function (_, Promise, util) {
  var PlaceData = {};

  var setPlaceStatus = function (place, type) {
    switch (type) {
    case 'resale':
      place.status = 'RESALE';
      break;
    case 'primary':
      place.status = 'OPEN';
      break;
    default:
      place.status = 'SOLD';
      break;
    }
  };

  var setPlaceOffer = function setPlaceOffer(place, offer) {
    place.offerIds = place.offerIds || [];
    var elementIndex = place.offerIds.indexOf(offer.offerId);
    if (elementIndex === -1) {
      place.offerIds.push(offer.offerId);
      place.offers = place.offers || [];
      place.offers.push(offer);
    }
  };

  var setPlaceOffers = function (offer, placeIds, places) {
    var index,
      length = placeIds.length;
    for (index = 0; index < length; index++) {
      var placeId = placeIds[index];
      var place = _.find(places, 'id', placeId);
      if (place) {
        setPlaceOffer(place, offer);

        // This will handle undefined
        if (_.every(place.offers, 'protected', true)) {
          place.isProtected = _.isEmpty(_.intersection(place.offerIds, PlaceData.unlockedOfferIds));
        } else {
          place.isProtected = false;
        }
      }
    }
  };

  var fetchPlaceOffers = function (plugin, offerData, places) {
    var offerIds = Object.keys(offerData),
      neededOffers = [],
      getOffers = plugin.urlBuilder.getOffers;
    var index,
      length = offerIds.length;
    for (index = 0; index < length; index++) {
      var offerId = offerIds[index];
      var offer = plugin.offers[offerId];
      if (!offer) {
        neededOffers.push(offerId)
      } else {
        setPlaceOffers(offer, offerData[offerId], places);
      }
    }
    var promises = [];
    for (index = 0; index < neededOffers.length; index++) {
      promises.push(getOffers(neededOffers[index]));
    }
    if (promises.length) {
      return Promise.all(promises)
        .then(function (offers) {
          offers.forEach(function (offer) {
            plugin.offers[offer.offerId] = offer;
            setPlaceOffers(offer, offerData[offer.offerId], places);
          });
        });
    } else {
      return Promise.resolve();
    }
  };

  var parseOffers = function (placeId, offerIds, placeOfferData) {
    var index, length = offerIds.length;
    for (index = 0; index < length; index++) {
      var offerId = offerIds[index];
      var places = placeOfferData[offerId] || [];
      places.push(placeId);
      placeOfferData[offerId] = places;
    }
    return placeOfferData;
  };

  var setPlaceAttributes = function (plugin, place, facet, placeOfferData) {
    var type = facet.inventoryTypes[0];

    setPlaceStatus(place, type);

    return parseOffers(place.id, facet.offers, placeOfferData);

  };

  var unSetPlaceStatus = function (core, places, placeIds) {
    var index,
      length = placeIds.length;
    for (index = 0; index < length; index++) {
      var placeId = placeIds[index];
      var place = _.find(places, 'id', placeId);
      setPlaceStatus(place, 'SOLD');
    }
  };

  var parsePlaceDataBySegment = function (plugin, facet, places, usedPlaces, placeOfferData) {
    var index,
      length = facet.length;
    for (index = 0; index < length; index++) {
      var placeIndex, data = facet[index],
        placeIds = data.places;
      for (adaPlaceIndex = 0; adaPlaceIndex < placeIds.length; adaPlaceIndex++) {
        var placeId = placeIds[adaPlaceIndex];
        var place = _.find(places, 'id', placeId);
        if (place) {
          usedPlaces.push(placeId);
          setPlaceAttributes(plugin, place, data, placeOfferData);
        }
      }

    }
    return placeOfferData;
  };

  var parsePlaceData = function (plugin, facets, places) {
    var index,
      usedPlaces = [],
      core = plugin.core,
      keys = Object.keys(facets),
      placeOfferData = plugin._placeOfferData,
      length = keys.length;
    for (index = 0; index < length; index++) {
      var segmentId = keys[index];
      var facet = facets[segmentId];
      parsePlaceDataBySegment(plugin, facet, places, usedPlaces, placeOfferData);
    }


    var allPlaces = util.pluck(places, 'id');
    var untouchedPlaces = _.difference(allPlaces, usedPlaces);
    if (untouchedPlaces.length) {
      unSetPlaceStatus(core, places, untouchedPlaces);
    }
    return fetchPlaceOffers(plugin, placeOfferData, places);
  };

  var getNeededSegments = function getNeededSegments(core, segmentIds, placeUpdateInterval) {
    var index, length = segmentIds.length,
      neededSegments = [],
      time = performance.now();
    for (index = 0; index < length; index++) {
      var segmentId = segmentIds[index];
      var segment = core.data.segmentsById[segmentId];
      if (segment.timeStamp < Math.abs(time - placeUpdateInterval)) {
        neededSegments.push(segmentId);
        segment.timeStamp = time;
      }
    }
    return neededSegments;
  };

  var appendArray = function appendArray(first, second) {
    var index = 0,
      length = second.length,
      element;
    while (index < length) {
      element = second[index];
      first.push(element);
      index++;
    }
  };

  var getPlaces = function getPlaces(segments) {
    var places = [],
      index, length = segments.length;
    for (index = 0; index < length; index++) {
      var segment = segments[index];
      if (segment.segments.length) {
        appendArray(places, getPlaces(segment.segments));
      }
      appendArray(places, segment.places);
    }
    return places;
  };

  var unlockPlaces = function unlockPlaces(plugin, placeIds) {
    var places = plugin.core.data.placesById,
      place, placeId,
      index, length;

    placeIds = placeIds || [];
    length = placeIds.length;

    for (index = 0; index < length; ++index) {
      placeId = placeIds[index];
      place = places[placeId];
      if (place) {
        place.isProtected = false;
      }
    }

  };

  var unlockPlacesForOffers = function unlockPlacesForOffers(plugin, offerIds) {
    var offerMap = plugin._placeOfferData,
      offerId,
      placeIds,
      length = offerIds.length,
      index;

    for (index = 0; index < length; ++index) {
      offerId = offerIds[index];
      placeIds = offerMap[offerId];
      unlockPlaces(plugin, placeIds);
    }

  };

  PlaceData.init = function (core) {
    this.unlockedOfferIds = [];
    this.unlockedOfferIdsByPass = {};
    core.Place.addPluginProperty('ada', false, true);
    core.Place.addPluginProperty('status', 'SOLD', true);
    core.Place.addPluginProperty('offers', null, false);
    core.Place.addPluginProperty('isProtected', false, true);
    core.Segment.addPluginProperty('timeStamp', 0, false);
  };

  PlaceData.getPlaceData = function (plugin, segments, placeUpdateInterval) {
    var getPlaceData = plugin.urlBuilder.getPlaceData,
      segments = segments || [],
      core = plugin.core;

    var segmentIds = getNeededSegments(core, segments, placeUpdateInterval);
    if (segmentIds.length === 0) {
      return Promise.resolve();
    }
    core.emit('place-availability-update-started');
    core.startLoading();
    var promises = [
      core.data.requestSegments(segmentIds),
      getPlaceData(segmentIds, plugin.resaleEnabled, plugin.platinumEnabled)
    ];
    return Promise.all(promises)
      .then(function (results) {
        var segments = results[0];
        var data = results[1];
        if (!data.facets.length) {
          core.emit('place-availability-update-complete');
          core.finishLoading();
          return Promise.resolve();
        }
        var allPlaces = getPlaces(segments);
        return parsePlaceData(plugin, _.groupBy(data.facets, 'shapes'), allPlaces)
          .then(function () {
            core.emit('place-availability-update-complete');
            core.finishLoading();
          });
      })
  };

  PlaceData.fetchPlaceData = function (plugin, segmentIds, placeUpdateInterval) {
    var self = this;
    var core = plugin.core;
    return this.getPlaceData(plugin, segmentIds, placeUpdateInterval)
      .then(function () {
        return Promise.delay(placeUpdateInterval)
      })
      .then(function () {
        return self.getPlaceData(plugin, core.map.renderedSections, placeUpdateInterval);
      });
  };

  PlaceData.unlockOffers = function (plugin, password, newUnlockedOfferIds) {
    this.unlockedOfferIdsByPass[password] = newUnlockedOfferIds;
    this.unlockedOfferIds = _(this.unlockedOfferIdsByPass).values().flatten().union().value();
    unlockPlacesForOffers(plugin, newUnlockedOfferIds);
  };

  return PlaceData;
});