PageSourceSearch

https://www.islandgetaway.com/sites/all/modules/rescms/rc_riot/js/mixins/RCRiotAvailPricing.js?tlsdzb

js islandgetaway.com collected 2026-09-26 08:34:29 UTC 14,066 bytes, 425 lines download raw bytes

1/**
2 * RCRiotAvailPricing RiotJS Mixin
3 */
4var RCRiotIsSearching;
5(function($) {
6  var lastSearch,
7    lastPricing,
8    avpdata = {};
9  var RCRiotAvailPricing = {
10    RCRiotAvailPricing: riot.observable(),
11    init: function() {
12      var tag = this;
13      this.mixin('RCRiotUtils');
14      if (typeof lastSearch == 'undefined') {
15        tag.loadLastSearch();
16        tag.loadLastPricing();
17      }
18
19      /**
20       *  Respond to BTLeads asking for metadata about items about to be
21       *  shared.
22       */
23      RiotTagsDispatch.on('BTLeadsShareItems', function(tag, items, entityType) {
24
25        if (entityType !== 'rc_core_item') {
26          return false;
27        }
28        items.items.forEach(function(value, key) {
29          if (avpdata['eid-' + value.item_id]) {
30            var pricingObj = avpdata['eid-' + value.item_id];
31
32            if(avpdata['eid-' + value.item_id].hasOwnProperty('prices') && avpdata['eid-' + value.item_id].prices.length) {
33              var pValue = parseFloat(avpdata['eid-' + value.item_id].prices[0].p).toFixed(2);
34              pricingObj.prices[0].p = parseFloat(pValue);
35              items.items[key].prices = pricingObj;
36            }
37          }
38        });
39      });
40
41      /**
42       * Respond to current search asking to remove all facets.
43       */
44      RiotTagsDispatch.on('RiotSolrCurrentSearchRemoveAll', function(currentSearch, widgetInstance) {
45        widgetInstance.manager.store.remove('rcav');
46      });
47    },
48    formatAvailPrice: function(val, digits, currency) {
49      return !val
50        ? ''
51        : val.toLocaleString('en', {
52            minimumFractionDigits: digits,
53            maximumFractionDigits: digits,
54            style: 'currency',
55            currency: currency || 'USD',
56            currencyDisplay: 'symbol',
57            useGrouping: true,
58          });
59    },
60    setAvailPricing: function(pricing, query) {
61      var eventData = {
62        pricing: pricing,
63        query: query,
64      };
65      avpdata = pricing;
66      RiotTagsDispatch.trigger('RCRiotPricingChanged', this, eventData);
67      this.RCRiotAvailPricing.trigger('PricingChanged', eventData);
68    },
69    getItemPricing: function(eid) {
70      return this.getAvailPricing()['eid-' + eid];
71    },
72    getAvailPricing: function() {
73      return avpdata;
74    },
75    storeLastSearch: function(params) {
76      localStorage.setItem('rcriotavailpricingparams', JSON.stringify(params));
77    },
78    loadLastSearch: function() {
79      var ls = JSON.parse(localStorage.getItem('rcriotavailpricingparams'));
80      lastSearch = ls;
81      return ls;
82    },
83    storeLastPricing: function(pricing) {
84      localStorage.setItem('rcriotavailpricingpricing', JSON.stringify(pricing));
85    },
86    loadLastPricing: function() {
87      var lr = JSON.parse(localStorage.getItem('rcriotavailpricingpricing'));
88      lastPricing = lr;
89      avpdata = lr || {};
90      return lr;
91    },
92    doSearch: function(query, store, multi) {
93      lastSearch = query;
94      var tag = this,
95        pricing = {};
96      multi = multi || 'all';
97      RCRiotIsSearching = true;
98      document.body.classList.add("rcav-loading-indicator");
99      var promise = $.Deferred(function() {
100        tag.RCRiotAvailPricing.trigger('SearchStart', query);
101        $.getJSON('/rcapi/item/avail/search', query)
102          .done(function(data) {
103            $(data).each(function(ind, val) {
104              var min = null,
105                max = null,
106                lowp = null;
107              if (this.prices.length > 1) {
108                switch (multi) {
109                  case 'first':
110                    this.prices = [this.prices[0]];
111                    break;
112                  case 'low':
113                    $(this.prices).each(function() {
114                      if (lowp == null || this.p < lowp.p) {
115                        lowp = this;
116                      }
117                    });
118                    this.prices = [lowp];
119                    break;
120                  case 'low_day':
121                    var lowestPerDay = function(prices) {
122                      var pricesByStart = {};
123                      var returnPrices = [];
124
125                      prices.forEach(function(price) {
126                        if (!pricesByStart.hasOwnProperty(price.bt) || pricesByStart[price.bt].p > price.p) {
127                          pricesByStart[price.bt] = price;
128                        }
129                      });
130
131                      for (var price in pricesByStart) {
132                        if (!pricesByStart.hasOwnProperty(price)) {
133                          continue;
134                        }
135
136                        returnPrices.push(pricesByStart[price]);
137                      }
138
139                      return returnPrices;
140                    };
141                    this.prices = lowestPerDay(this.prices);
142                    break;
143                }
144              }
145              $(this.prices).each(function() {
146                var price = parseInt(this.p, 10);
147                var travelers = parseInt(this.qp.rcav.adult, 10) + parseInt(this.qp.rcav.child, 10);
148                if(this.qp.senior) {
149                  travelers += parseInt(this.qp.rcav.senior, 10);
150                }
151                this.ppp = price / travelers;
152                // Set begin and end date timestamps according to browser timezone settings
153                if (typeof this.b != 'undefined') {
154                  this.bt = tag.parseDate(this.b);
155                  this.et = tag.parseDate(this.e);
156                  this.nt = ((this.et - this.bt) / 1000) / 86400;
157                  this.wk = (this.nt) / 7;
158                  this.ppn = price / this.nt;
159                  this.ppw = price / this.wk;
160                  this.pppn = (price / this.nt) / travelers;
161                }
162
163                if (min == null || this.p < min) {
164                  min = this.p;
165                }
166                if (max == null || this.p > max) {
167                  max = this.p;
168                }
169                //@todo: decodeURIComponent - do we need it?
170                this['itemBuyURL'] = decodeURIComponent(tag.RCRiotUtils.getBuyUrl(this));
171                this['itemURLHash'] = '#' + $.param({ rcav: JSON.stringify(this.qp) });
172              });
173              this.range = [min, max];
174            });
175            lastPricing = data;
176            $(data).each(function(ind, obj) {
177              pricing['eid-' + obj.eid] = obj;
178            });
179            if (store) {
180              this.storeLastSearch(query);
181              this.storeLastPricing(pricing);
182            }
183            tag.setAvailPricing(pricing, query);
184            promise.resolve({
185              pricing: pricing,
186              query: query,
187            });
188          })
189          .always(function() {
190            tag.RCRiotAvailPricing.trigger('SearchStop');
191            RCRiotIsSearching = false;
192            document.body.classList.remove("rcav-loading-indicator");
193          });
194      });
195      return promise;
196    },
197    getLastSearch: function() {
198      return lastSearch;
199    },
200    setLastSearch: function(query) {
201      lastSearch = query;
202    },
203    getItemPriceRange: function(eid) {
204      var pricing = this.getItemPricing(eid),
205        min = null,
206        max = null;
207      if (typeof pricing != 'undefined') {
208        $(pricing.prices).each(function() {
209          if (min == undefined || min.p > this.p) {
210            min = this;
211          }
212          if (max == undefined || max.p < this.p) {
213            max = this;
214          }
215        });
216      }
217      return [min, max];
218    },
219  getItemPriceRangePerNight: function(eid) {
220      var pricing = this.getItemPricing(eid),
221        min = null,
222        max = null;
223      if (typeof pricing != 'undefined') {
224        $(pricing.prices).each(function() {
225          if (min == undefined || min.ppn > this.ppn) {
226            min = this;
227          }
228          if (max == undefined || max.ppn < this.ppn) {
229            max = this;
230          }
231        });
232      }
233      return [min, max];
234    },
235    getItemPriceRangePerWeek: function(eid) {
236      var pricing = this.getItemPricing(eid),
237        min = null,
238        max = null;
239      if (typeof pricing != 'undefined') {
240        $(pricing.prices).each(function() {
241          if (min == undefined || min.ppw > this.ppw) {
242            min = this;
243          }
244          if (max == undefined || max.ppw < this.ppw) {
245            max = this;
246          }
247        });
248      }
249      return [min, max];
250    },
251    getItemPriceRangePerPerson: function(eid) {
252      var pricing = this.getItemPricing(eid),
253        min = null,
254        max = null;
255      if (typeof pricing != 'undefined') {
256        $(pricing.prices).each(function() {
257          if (min == undefined || min.ppp > this.ppp) {
258            min = this;
259          }
260          if (max == undefined || max.ppp < this.ppp) {
261            max = this;
262          }
263        });
264      }
265      return [min, max];
266    },
267    getItemPriceRangePerPersonPerNight: function(eid) {
268      var pricing = this.getItemPricing(eid),
269        min = null,
270        max = null;
271      if (typeof pricing != 'undefined') {
272        $(pricing.prices).each(function() {
273          if (min == undefined || min.pppn > this.pppn) {
274            min = this;
275          }
276          if (max == undefined || max.pppn < this.pppn) {
277            max = this;
278          }
279        });
280      }
281      return [min, max];
282    },
283    getItemSavingsRange: function(eid) {
284      var pricing = this.getItemPricing(eid),
285        min = null,
286        max = null;
287      if (typeof pricing != 'undefined') {
288        $(pricing.prices).each(function() {
289          if (typeof this.s != 'undefined' && (min == undefined || min.s > this.s)) {
290            min = this;
291          }
292          if (typeof this.s != 'undefined' && (max == undefined || max.s < this.s)) {
293            max = this;
294          }
295        });
296      }
297      return [min, max];
298    },
299    formatItemPriceRange: function(eid, decs, format) {
300      decs = isNaN(decs) ? 0 : decs;
301      var range = this.getItemPriceRange(eid),
302        ret = '';
303      if (range[0] && range[0].p > 0) {
304        ret = this.RCRiotUtils.formatPrice(range[0], decs, format);
305        if (range[0].p != range[1].p) {
306          ret += ' - ' + this.RCRiotUtils.formatPrice(range[1], decs, format);
307        }
308      }
309      return ret;
310    },
311    formatItemSavingsRange: function(eid, decs, format) {
312      decs = isNaN(decs) ? 0 : decs;
313      var range = this.getItemSavingsRange(eid),
314        ret = '';
315      if (range[1] != null && typeof range[1].s != 'undefined' && range[1].s > 0) {
316        ret = this.RCRiotUtils.formatHelper(parseFloat(range[1].s), range[1], decs, format);
317      }
318      return ret;
319    },
320    getLastSearchQuery: function() {
321      return lastSearch;
322    },
323    getItemHasPackage: function(eid) {
324      var ret = false,
325        ip = this.getItemPricing(eid),
326        ind;
327      if (typeof ip != 'undefined' && typeof ip.prices != 'undefined') {
328        for (ind in ip.prices) {
329          if (this.getPriceHasPackage(ip.prices[ind])) {
330            ret = true;
331            break;
332          }
333        }
334      }
335      return ret;
336    },
337    getPriceIsAlternate: function(price) {
338      var ret = true;
339      if(typeof price == undefined || typeof price.qp == undefined) {
340        return ret;
341      }
342      ret = price.qp.rcav.begin !== lastSearch.rcav.begin;
343      return ret;
344    },
345    getPriceHasPackage: function(price) {
346      var ret = false;
347      if(typeof price == undefined || typeof price.qp == undefined) {
348        return ret;
349      }
350      if (typeof price.qp.rcav.IDs != 'undefined' && typeof price.qp.rcav.IDs[2] != 'undefined') {
351        ret = true;
352      }
353      return ret;
354    },
355    getPriceHasCoupon: function(price) {
356      var ret = false;
357      if(typeof price == undefined || typeof price.qp == undefined) {
358        return ret;
359      }
360
361      if (typeof price.qp.rcav.coupon != 'undefined' && price.qp.rcav.coupon != '') {
362        ret = true;
363      }
364      return ret;
365    },
366    getPriceHasSavings: function(price) {
367      var ret = false;
368      if(typeof price == undefined || typeof price.qp == undefined) {
369        return ret;
370      }
371      if (typeof price.s != 'undefined' && parseFloat(price.s) > 0) {
372        ret = true;
373      }
374      return ret;
375    },
376    parseDate: function(datestr) {
377      var dt = new Date(0, 0, 0, 0, 0, 0, 0);
378      var parts = datestr.split('-');
379      if (parts.length == 3) {
380        dt.setFullYear(parts[0], parts[1] - 1, parts[2]);
381      } else {
382        parts = datestr.split('/');
383        if (parts.length == 3) {
384          dt.setFullYear(parts[2], parts[0] - 1, parts[1]);
385        }
386      }
387      return dt.getTime();
388    },
389  };
390  riot.mixin('RCRiotAvailPricing', RCRiotAvailPricing);
391
392  $(document).ready(function() {
393    if (typeof RiotSolrItemSortHandlers !== 'undefined') {
394      RiotSolrItemSortHandlers['sortPrice'] = {
395        primer: function(eid, reverse) {
396          var pricing = RCRiotAvailPricing.getItemPricing(eid);
397          if (pricing && pricing.hasOwnProperty('range') && Array.isArray(pricing.range) && pricing.range.length >= 2) {
398            // Price range values are low [0] and high [1].
399            return reverse ? parseFloat(pricing.range[1]) : parseFloat(pricing.range[0]);
400          }
401          // Don't affect the sort if we have no prices.
402          return 0;
403        },
404        callback: function(items, field, reverse, secondary) {
405          var self = this,
406            r = !reverse ? 1 : -1;
407          items.sort(function(a, b) {
408            var a_field = self.primer(a[field], reverse),
409              b_field = self.primer(b[field], reverse),
410              order = r * ((a_field > b_field) - (b_field > a_field));
411
412            if (!order &&
413                secondary &&
414                typeof RiotSolrItemSortHandlers.secondarySortOrder === 'function') {
415              order = RiotSolrItemSortHandlers.secondarySortOrder(a, b, secondary);
416            }
417
418            return order;
419          });
420          return items;
421        },
422      };
423    }
424  });
425})(jQuery);

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.