'use strict'; /* US - App Module */ var app = angular.module('wineCellarApp', [ 'wineCellarConstants', 'wineCellarControllers', 'wineCellarDirectives', 'wineCellarFilters', 'utilServices', 'apiServices', 'apiBvServices', 'ui.router', 'ngResource', 'ngSanitize', 'ngAnimate', 'ui.bootstrap.pagination', 'ui.bootstrap.tooltip', 'ui.bootstrap.position', 'ui.bootstrap.bindHtml', 'ui.bootstrap.popover' ]); app.config([ '$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) { // For any unmatched url, redirect to / $urlRouterProvider.otherwise('/purchased'); // Now set up the states $stateProvider .state('purchased', { url: '/purchased', templateUrl: '/assets/views/au/wpe/wine_grid_purchased.html', controller: 'purchaseController' }) .state('favorites', { url: '/favorites', templateUrl: '/assets/views/au/wpe/wine_grid_favourites.html', controller: 'favouritesController' }) .state('rated', { url: '/top-rated', templateUrl: '/assets/views/au/wpe/wine_grid_rated.html', controller: 'ratingsController' }) .state('recommendations', { url: '/recommendations', templateUrl: '/assets/views/au/wpe/wine_grid_recommendations.html', controller: 'recommendationsController' }) .state('dislike', { url: '/dont-send', templateUrl: '/assets/views/au/wpe/wine_grid_dislike.html', controller: 'dislikeController' }); } ]); if (!cellarOverrides) { var cellarOverrides = {}; } // Hack for AU (avoid DataLayer Errors) if (!dataLayer) { var dataLayer = []; } var wineCellarControllers = angular.module('wineCellarControllers', []); wineCellarControllers.controller('favouritesController', [ '$scope', '$rootScope', 'api', '$resource', 'util', 'bv_config', '$window', '$location', function($scope, $rootScope, api, $resource, util, bv_config, $window, $location) { $scope.tallestElement = 0; $scope.brand = util.brand(); $scope.brandShort = util.brandInfo(util.brand()).shorthand; $scope.country = util.country(); $scope.brandBtn = 'btn btn-primary'; $scope.defaultBtn = 'btn btn-default'; $scope.brandURL = util.domain(); $scope.fav = util.country() === 'uk' ? 'favourite' : 'favorite'; $scope.userLocale = dataLayer[0].userLocale; $scope.items = []; $scope.dataReady = false; $scope.dataEmpty = false; $scope.loadingStatusMessage = true; $scope.loadingErrorMessage = false; $scope.loading = true; $scope.orderProp = '-userItemDetails.lastUpdatedDate'; $scope.cartAdded = false; $scope.dwfav = $location.search().dw_fav; // console.log($location); $scope.baseURL = $location.host(); var fullBase = $scope.baseURL + ':' + $location.port(); $scope.baseURL = $location.port() != '443' ? fullBase : $scope.baseURL; // BV Config $scope.getBVConfig = function() { var environment = util.env(); var currentBrand = util.brand(); var currentCountry = util.country(); // console.log('env', environment); if (environment.indexOf('uat') > -1 || environment.indexOf('st') > -1 || environment.indexOf('webdev') > -1) { $scope.bvConfig = bv_config.staging[currentCountry][currentBrand]; } else { $scope.bvConfig = bv_config.production[currentCountry][currentBrand]; } }; // Load Favourites from API - Attach data to view $scope.getFavouritesList = function() { $scope.items = []; api.favourites .list( {}, function(successResult) { // console.log('success'); }, function(errorResult) { // console.log('error', errorResult); if (errorResult.status === 405 || errorResult.status === 500 || errorResult.status === 404) { //console.log('500 - 405 error'); } $scope.loadingStatusMessage = false; $scope.loadingErrorMessage = true; $scope.loading = false; } ) .$promise.then(function(data) { // console.log('resource', data); if (data.response.itemListInfo.numberOfItems === 0) { $scope.loadingStatusMessage = false; $scope.dataReady = false; $scope.loading = false; $scope.dataEmpty = true; } else { $scope.dataReady = true; $scope.dataEmpty = false; $scope.loading = false; $scope.loadingStatusMessage = false; angular.forEach(data.response.userItems, function(item, index) { item.color = item.product.colourId; item.colorName = item.product.colourName; item.longName = item.product.name + ' ' + item.product.vintage; $scope.items.push(item); $scope.getAlternativeProduct(item, index); }); $scope.setPagination(); } }); }; // Get alternative product for out of stock products $scope.getAlternativeProduct = function(item, index) { if(item.product.inventoryInfo && item.product.inventoryInfo.summaryAvailabilityStatus === 'in_stock') { return; } api.alternateItem.list( { itemcode: item.product.itemCode }, function() { }, function() { } ) .$promise.then(function(data) { if(data.response.relatedProducts.length > 0) { $scope.items[index].alternateItem = data.response.relatedProducts[0]; } } ); }; $scope.addFavorite = function(itemCode, name, updateScreen) { api.favourites.save( { item: itemCode }, function(successResult) { //$window._gaq.push(['_trackEvent', 'Favorites', 'Added_Wine_Cellar', name]); dataLayer.push({ event: 'GAevent', eventCategory: 'Favorites', eventAction: 'Added_Wine_Cellar', eventLabel: name }); // console.log('Product has been added to '+$scope.fav); if(dataLayer[0].userLocale === 'zh_HK_LW' || dataLayer[0].userLocale === 'zh_HK_HKLW') { $scope.$broadcast( 'flashNotification::message', '已成功將此酒款加到「我最愛的葡萄酒」。' ); } else { $scope.$broadcast( 'flashNotification::message', 'The ' + $scope.fav + ' has been successfully added to your wine cellar.' ); } // console.log(updateScreen); if (updateScreen) { $scope.getFavouritesList(); } if (util.country() === 'us') { favoritesHeader.updateFavs(); } }, function(errorResult) { if (errorResult.status === 422) { // console.log('422 Error - Product has already been added to '+$scope.fav+'.'); $scope.$broadcast( 'flashNotification::message', "Sorry, we're having trouble adding this product to your " + $scope.fav + '. Either you have already added it, or we are experiencing a technical issue. Please try refreshing your browser, and if the problem persists, contact customer care.' ); } if (updateScreen) { $scope.getFavouritesList(); } } ); }; $scope.removeFavorite = function(itemCode, name) { $scope.removeName = name; api.favourites .del({ item: itemCode }) .$promise.then(function(response) { api.favourites.list().$promise.then(function(response) { if (response.userItems == '') { //$window._gaq.push(['_trackEvent', 'Favorites', 'Removed_Wine_Cellar', name]); dataLayer.push({ event: 'GAevent', eventCategory: 'Favorites', eventAction: 'Removed_Wine_Cellar', eventLabel: name }); // console.log('less than 1 item in list.'); if(dataLayer[0].userLocale === 'zh_HK_LW' || dataLayer[0].userLocale === 'zh_HK_HKLW') { $scope.$broadcast( 'flashNotification::message', '已成功從「我最愛的葡萄酒」移除此酒款。' ); } else { $scope.$broadcast( 'flashNotification::message', 'The ' + $scope.fav + ' has been successfully removed from your wine cellar.' ); } } else { //$window._gaq.push(['_trackEvent', 'Favorites', 'Removed_Wine_Cellar', name]); dataLayer.push({ event: 'GAevent', eventCategory: 'Favorites', eventAction: 'Removed_Wine_Cellar', eventLabel: name }); // console.log('more than 1 item in list.'); if(dataLayer[0].userLocale === 'zh_HK_LW' || dataLayer[0].userLocale === 'zh_HK_HKLW') { $scope.$broadcast( 'flashNotification::message', '已成功從「我最愛的葡萄酒」移除此酒款。' ); } else { $scope.$broadcast( 'flashNotification::message', 'The ' + $scope.fav + ' has been successfully removed from your wine cellar.' ); } } if (util.country() === 'us') { favoritesHeader.updateFavs(); } }); }); }; $scope.favouritesSearch = function (item) { if ($scope.filterText == undefined) { return true; } else { if (item.product.name?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.grapeName?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.countryName?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.vintage?.indexOf($scope.filterText) !== -1) { return true; } } return false; } // -------- Color Filter -------- $scope.colorFilter = function($event, filterVal) { $('ul.nav-tabs li').removeClass('active'); $($event.target) .parent() .toggleClass('active'); if(dataLayer[0].country === 'tw' || (dataLayer[0].userLocale === "zh_HK_LW" || dataLayer[0].userLocale === "zh_HK_HKLW")) { $scope.filters.colorName = filterVal; } else { $scope.filters.color = filterVal; } }; // -------- PAGINATION -------- $scope.setPagination = function() { $scope.currentPage = 1; $scope.maxSize = 10; $scope.perPage = 10; }; $scope.setPage = function(pageNo) { $scope.currentPage = pageNo; }; // -------- Broadcast Events -------- $scope.previewItem = function(itemcode, $event) { if($event) { $event.preventDefault(); } $rootScope.$broadcast('quickPreview', itemcode); }; $scope.rateItem = function(itemcode, itemname, itemvintage, itemimage) { $rootScope.$broadcast('quickRate', itemcode, itemname, itemvintage, itemimage); }; // -------- INITIAL VARIABLES -------- if ($scope.dwfav) { $scope.dwfav = $scope.dwfav.split('-'); var favLength = $scope.dwfav.length - 1; var updateScreen = false; for (var i = 0; i < favLength + 1; i++) { if (favLength == i) { updateScreen = true; } $scope.addFavorite($scope.dwfav[i], 'triggeredByEmail_' + $scope.dwfav, updateScreen); } } else { $scope.getFavouritesList(); } $scope.getBVConfig(); $scope.filters = {}; if(dataLayer[0].country === 'tw' || (dataLayer[0].userLocale === "zh_HK_LW" || dataLayer[0].userLocale === "zh_HK_HKLW")) { $scope.categories = ['紅酒', '白酒', '粉紅酒', '氣泡酒']; } else { $scope.categories = ['Red', 'White', 'Rose', 'Sparkling']; } } ]); wineCellarControllers.controller('dislikeController', [ '$scope', '$rootScope', 'api', '$resource', 'util', 'bv_config', '$window', function($scope, $rootScope, api, $resource, util, bv_config, $window) { $scope.tallestElement = 0; $scope.brand = util.brand(); $scope.brandShort = util.brandInfo(util.brand()).shorthand; $scope.country = util.country(); $scope.userLocale = dataLayer[0].userLocale; $scope.brandBtn = 'btn btn-primary'; $scope.defaultBtn = 'btn btn-default'; $scope.brandURL = util.domain(); $scope.items = []; $scope.dataReady = false; $scope.dataEmpty = false; $scope.loadingStatusMessage = true; $scope.loadingErrorMessage = false; $scope.loading = true; $scope.orderProp = '-userItemDetails.lastUpdatedDate'; $scope.cartAdded = false; // Load Favourites from API - Attach data to view $scope.getDislikeList = function() { api.dislike .list( {}, function(successResult) { // console.log('success'); }, function(errorResult) { // console.log('error', errorResult); if (errorResult.status === 405 || errorResult.status === 500 || errorResult.status === 404) { //console.log('500 - 405 error'); } $scope.loadingStatusMessage = false; $scope.loadingErrorMessage = true; $scope.loading = false; } ) .$promise.then(function(data) { // console.log('resource', data); if (data.response.itemListInfo.numberOfItems === 0) { $scope.loadingStatusMessage = false; $scope.dataReady = false; $scope.loading = false; $scope.dataEmpty = true; } else { $scope.dataReady = true; $scope.dataEmpty = false; $scope.loading = false; $scope.loadingStatusMessage = false; angular.forEach(data.response.userItems, function(item) { item.color = item.product.colourId; item.longName = item.product.name + ' ' + item.product.vintage; $scope.items.push(item); $scope.getAlternativeProduct(item, $scope.items.length - 1); item.whereUsed.inDislike = true; }); $scope.setPagination(); } }); }; // Get alternative product for out of stock products $scope.getAlternativeProduct = function(item, index) { if(item.product.inventoryInfo && item.product.inventoryInfo.summaryAvailabilityStatus === 'in_stock') { return; } api.alternateItem.list( { itemcode: item.product.itemCode }, function() { }, function() { } ) .$promise.then(function(data) { if(data.response.relatedProducts.length > 0) { $scope.items[index].alternateItem = data.response.relatedProducts[0]; } } ); }; $scope.addDislike = function(itemCode, name) { api.dislike.add( { item: itemCode }, function(successResult) { dataLayer.push({ event: 'GAevent', eventCategory: 'Not For Me', eventAction: 'Added_Wine_Cellar', eventLabel: name }); $scope.$broadcast( 'flashNotification::message', 'The wine has been successfully added to your Not For Me List.' ); }, function(errorResult) { if (errorResult.status === 422) { $scope.errorMessage = "Sorry, we're having trouble adding this product to your Not For Me List. Either you have already added it, or we are experiencing a technical issue. Please try refreshing your browser, and if the problem persists, contact customer care."; } } ); }; $scope.removeDislike = function(itemCode, name) { api.dislike.del( { item: itemCode }, function(successResult) { dataLayer.push({ event: 'GAevent', eventCategory: 'Not For Me', eventAction: 'Removed_Wine_Cellar', eventLabel: name }); $scope.$broadcast( 'flashNotification::message', 'The wine has been successfully removed from your Not For Me List.' ); }, function(errorResult) { if (errorResult.status === 422) { $scope.errorMessage = "Sorry, we're having trouble adding this product to your Not For Me List. Either you have already added it, or we are experiencing a technical issue. Please try refreshing your browser, and if the problem persists, contact customer care."; } } ); }; $scope.dislikeSearch = function (item) { if ($scope.filterText == undefined) { return true; } else { if (item.product.name?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.grapeName?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.countryName?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.vintage?.indexOf($scope.filterText) !== -1) { return true; } } return false; } // -------- Color Filter -------- $scope.colorFilter = function($event, filterVal) { $('ul.nav-tabs li').removeClass('active'); $($event.target) .parent() .toggleClass('active'); $scope.filters.color = filterVal; }; // -------- PAGINATION -------- $scope.setPagination = function() { $scope.currentPage = 1; $scope.maxSize = 16; $scope.perPage = 16; }; $scope.setPage = function(pageNo) { $scope.currentPage = pageNo; }; // -------- Broadcast Events -------- $scope.previewItem = function(itemcode, $event) { if($event) { $event.preventDefault(); } $rootScope.$broadcast('quickPreview', itemcode); }; // -------- INITIAL VARIABLES -------- $scope.getDislikeList(); $scope.filters = {}; $scope.categories = ['Red', 'White', 'Rose', 'Sparkling']; } ]); wineCellarControllers.controller('purchaseController', [ '$scope', '$rootScope', 'api', '$resource', 'util', 'bv_config', '$window', '$location', function($scope, $rootScope, api, $resource, util, bv_config, $window, $location) { // Variables $scope.tallestElement = 0; $scope.brand = util.brand(); $scope.brandShort = util.brandInfo(util.brand()).shorthand; $scope.country = util.country(); $scope.userLocale = dataLayer[0].userLocale; $scope.brandURL = util.domain(); $scope.brandBtn = 'btn btn-primary'; $scope.defaultBtn = 'btn btn-default'; $scope.fav = util.country() === 'uk' ? 'favourite' : 'favorite'; $scope.skus = []; $scope.dataReady = false; $scope.dataEmpty = false; $scope.loadingStatusMessage = true; $scope.loadingErrorMessage = false; $scope.loading = true; $scope.orderProp = '-userItemDetails.lastShipmentDate'; $scope.dwfav = $location.search().dw_fav; $scope.items = []; $scope.baseURL = $location.host(); var fullBase = $scope.baseURL + ':' + $location.port(); $scope.baseURL = $location.port() != '443' ? fullBase : $scope.baseURL; // BV Config $scope.getBVConfig = function() { var environment = util.env(); var currentBrand = util.brand(); var currentCountry = util.country(); // console.log('env', environment); if (environment === 'uat' || environment === 'webdev') { $scope.bvConfig = bv_config.staging[currentCountry][currentBrand]; } else { $scope.bvConfig = bv_config.production[currentCountry][currentBrand]; } }; // Load Purchases from API - Attach data to view $scope.getPurchasedList = function() { api.purchases .list( {}, function(successResult) { // console.log('data loaded.'); }, function(errorResult) { // console.log('error', errorResult); if (errorResult.status === 405 || errorResult.status === 500 || errorResult.status === 404) { //console.log('500 - 405 error'); } $scope.loadingStatusMessage = false; $scope.loadingErrorMessage = true; $scope.loading = false; } ) .$promise.then(function(data) { // console.log('resource', data); if (data.response.itemListInfo.numberOfItems === 0) { $scope.loadingStatusMessage = false; $scope.dataReady = false; $scope.loading = false; $scope.dataEmpty = true; } else { $scope.dataReady = true; $scope.dataEmpty = false; $scope.loading = false; $scope.loadingStatusMessage = false; angular.forEach(data.response.userItems, function(item) { // Only push wines to the item array if (item.product.productType === 'wine' || item.product.productType === 'nonwine') { if ($scope.dislikeList.indexOf(item.product.itemCode) > -1) { item.whereUsed.inDoNotSend = true; } item.color = item.product.colourId; item.longName = item.product.name + ' ' + item.product.vintage; $scope.items.push(item); $scope.getAlternativeProduct(item, $scope.items.length - 1); } }); $scope.setPagination(); } }); }; // Get alternative product for out of stock products $scope.getAlternativeProduct = function(item, index) { if(item.product.inventoryInfo && item.product.inventoryInfo.summaryAvailabilityStatus === 'in_stock') { return; } api.alternateItem.list( { itemcode: item.product.itemCode }, function() { }, function() { } ) .$promise.then(function(data) { if(data.response.relatedProducts.length > 0) { $scope.items[index].alternateItem = data.response.relatedProducts[0]; } } ); }; $scope.removeFavorite = function(itemCode, name) { api.favourites.del( { item: itemCode }, function(successResult) { //$window._gaq.push(['_trackEvent', 'Favorites', 'Removed_Wine_Cellar', name]); dataLayer.push({ event: 'GAevent', eventCategory: 'Favorites', eventAction: 'Removed_Wine_Cellar', eventLabel: name }); //console.log('The '+$scope.fav+' has been successfully removed from your wine cellar.'); if(dataLayer[0].userLocale === 'zh_HK_LW' || dataLayer[0].userLocale === 'zh_HK_HKLW') { $scope.$broadcast( 'flashNotification::message', '已成功從「我最愛的葡萄酒」移除此酒款。' ); } else { $scope.$broadcast( 'flashNotification::message', 'The ' + $scope.fav + ' has been successfully removed from your wine cellar.' ); } if (util.country() === 'us') { favoritesHeader.updateFavs(); } }, function(errorResult) { if (errorResult.status === 422) { $scope.errorMessage = "Sorry, we're having trouble adding this product to your " + $scope.fav + '. Either you have already added it, or we are experiencing a technical issue. Please try refreshing your browser, and if the problem persists, contact customer service.'; //console.log('Product has already been added to '+$scope.fav+'.'); } } ); }; $scope.addFavorite = function(itemCode, name, updateScreen) { api.favourites.save( { item: itemCode }, function(successResult) { dataLayer.push({ event: 'GAevent', eventCategory: 'Favorites', eventAction: 'Added_Wine_Cellar', eventLabel: name }); // $window._gaq.push(['_trackEvent', 'Favorites', 'Added_Wine_Cellar', name]); // console.log('The favorite has been successfully added to your wine cellar.'); if(dataLayer[0].userLocale === 'zh_HK_LW' || dataLayer[0].userLocale === 'zh_HK_HKLW') { $scope.$broadcast( 'flashNotification::message', '已成功將此酒款加到「我最愛的葡萄酒」。' ); } else { $scope.$broadcast( 'flashNotification::message', 'The ' + $scope.fav + ' has been successfully added to your wine cellar.' ); } // console.log(updateScreen); if (updateScreen && name == 'triggeredByEmail_') { $scope.getDislikeList(); } if (util.country() === 'us') { favoritesHeader.updateFavs(); } }, function(errorResult) { if (errorResult.status === 422) { // console.log('422 Error - Product has already been added to '+$scope.fav+'.'); $scope.errorMessage = "Sorry, we're having trouble removing this product from your " + $scope.fav + '. Either you have already removed it, or we are experiencing a technical issue. Please try refreshing your browser, and if the problem persists, contact customer service.'; } if (updateScreen) { $scope.getDislikeList(); } } ); }; // Load Favourites from API - Attach data to view $scope.getDislikeList = function() { api.dislike .list( {}, function(successResult) { // console.log('success'); }, function(errorResult) { // console.log('error', errorResult); if (errorResult.status === 405 || errorResult.status === 500 || errorResult.status === 404) { //console.log('500 - 405 error'); } } ) .$promise.then(function(data) { var userItems = data.response.userItems || []; if (userItems.length > 0) { angular.forEach(userItems, function(item) { $scope.dislikeList.push(item.product.itemCode); }); } $scope.getPurchasedList(); }); }; $scope.addDislike = function(itemCode, name) { api.dislike.add( { item: itemCode }, function(successResult) { dataLayer.push({ event: 'GAevent', eventCategory: 'Not For Me', eventAction: 'Added_Wine_Cellar', eventLabel: name }); $scope.$broadcast( 'flashNotification::message', 'The wine has been successfully added to your Not For Me List.' ); }, function(errorResult) { if (errorResult.status === 422) { $scope.errorMessage = "Sorry, we're having trouble adding this product to your Not For Me List. Either you have already added it, or we are experiencing a technical issue. Please try refreshing your browser, and if the problem persists, contact customer care."; } } ); }; $scope.removeDislike = function(itemCode, name) { api.dislike.del( { item: itemCode }, function(successResult) { dataLayer.push({ event: 'GAevent', eventCategory: 'Not For Me', eventAction: 'Removed_Wine_Cellar', eventLabel: name }); $scope.$broadcast( 'flashNotification::message', 'The wine has been successfully removed from your Not For Me List.' ); }, function(errorResult) { if (errorResult.status === 422) { $scope.errorMessage = "Sorry, we're having trouble adding this product to your Not For Me List. Either you have already added it, or we are experiencing a technical issue. Please try refreshing your browser, and if the problem persists, contact customer care."; } } ); }; //onclick rating - text $scope.ratingText = function(name) { dataLayer.push({ event: 'GAevent', eventCategory: 'Rate this wine', eventAction: 'Click_Text', eventLabel: name }); }; //onclick rating - star $scope.ratingStar = function(name) { dataLayer.push({ event: 'GAevent', eventCategory: 'Rate this wine', eventAction: 'Click_Star', eventLabel: name }); }; $scope.purchaseSearch = function (item) { if ($scope.filterText == undefined) { return true; } else { if (item.product.name?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.grapeName?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.countryName?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.vintage?.indexOf($scope.filterText) !== -1) { return true; } } return false; } $scope.colorFilter = function($event, filterVal) { $('ul.nav-tabs li').removeClass('active'); $($event.target) .parent() .toggleClass('active'); $scope.filters.color = filterVal; }; // -------- Broadcast Events -------- $scope.previewItem = function(itemcode, $event) { if($event) { $event.preventDefault(); } //console.log('broadcast','quickPreview'); $rootScope.$broadcast('quickPreview', itemcode); }; $scope.rateItem = function(itemcode, itemname, itemvintage, itemimage) { $rootScope.$broadcast('quickRate', itemcode, itemname, itemvintage, itemimage); }; // -------- PAGINATION -------- $scope.setPagination = function() { $scope.currentPage = 1; $scope.maxSize = 16; $scope.perPage = 16; }; $scope.setPage = function(pageNo) { $scope.currentPage = pageNo; }; // -------- INITIAL VARIABLES -------- if ($scope.dwfav) { $scope.dwfav = $scope.dwfav.split('-'); var favLength = $scope.dwfav.length - 1; var updateScreen = false; // console.log('fav' + favLength); for (var i = 0; i < favLength + 1; i++) { if (favLength == i) { updateScreen = true; } $scope.addFavorite($scope.dwfav[i], 'triggeredByEmail_' + $scope.dwfav, updateScreen); // console.log('i' + i); } } else { $scope.getDislikeList(); // console.log('else'); } $scope.getBVConfig(); $scope.brand = util.brandInfo(); $scope.filters = {}; $scope.dislikeList = []; $scope.categories = ['Red', 'White', 'Rose', 'Sparkling']; } ]); wineCellarControllers.controller('ratingsController', [ '$scope', '$rootScope', 'api', '$resource', 'util', 'bv_config', '$window', '$location', function($scope, $rootScope, api, $resource, util, bv_config, $window, $location) { $scope.tallestElement = 0; $scope.brand = util.brand(); $scope.brandShort = util.brandInfo(util.brand()).shorthand; $scope.country = util.country(); $scope.brandBtn = 'btn btn-primary'; $scope.defaultBtn = 'btn btn-default'; $scope.brandURL = util.domain(); $scope.userLocale = dataLayer[0].userLocale; var country = util.country(); $scope.fav = country === 'uk' ? 'favourite' : 'favorite'; $scope.items = []; $scope.dataReady = false; $scope.dataEmpty = false; $scope.loadingStatusMessage = true; $scope.loadingErrorMessage = false; $scope.loading = true; $scope.ratingLimit = $scope.brand === 'zagat' ? 2.5 : 4; $scope.ratingLimit = country === 'uk' ? 0 : $scope.ratingLimit; $scope.orderProp = '-userItemDetails.lastUpdatedDate'; $scope.dwfav = $location.search().dw_fav; // console.log($location); $scope.baseURL = $location.host(); var fullBase = $scope.baseURL + ':' + $location.port(); $scope.baseURL = $location.port() != '443' ? fullBase : $scope.baseURL; // BV Config $scope.getBVConfig = function() { var environment = util.env(); var currentBrand = util.brand(); var currentCountry = util.country(); // console.log('env', environment); if (environment === 'uat' || environment === 'webdev') { $scope.bvConfig = bv_config.staging[currentCountry][currentBrand]; } else { $scope.bvConfig = bv_config.production[currentCountry][currentBrand]; } }; // Load Ratings from API - Attach data to view $scope.getRatedList = function() { api.ratings .list( {}, function(successResult) { // console.log('success'); }, function(errorResult) { // console.log('error', errorResult); if (errorResult.status === 405 || errorResult.status === 500 || errorResult.status === 404) { //console.log('500 - 405 error'); } $scope.loadingStatusMessage = false; $scope.loadingErrorMessage = true; $scope.loading = false; } ) .$promise.then(function(data) { // console.log('resource',data); $scope.dataReady = true; if (data.response.itemListInfo.numberOfItems === 0) { $scope.loadingStatusMessage = false; $scope.dataReady = false; $scope.loading = false; $scope.dataEmpty = true; } else { $scope.dataReady = true; $scope.dataEmpty = false; $scope.loading = false; $scope.loadingStatusMessage = false; angular.forEach(data.response.userItems, function(item) { item.color = item.product.colourId; item.longName = item.product.name + ' ' + item.product.vintage; var rating = $scope.brand === 'zagat' ? item.ratingDetails?.userProductRating?.zagatAverageUserRating : item.ratingDetails?.userProductRating?.userOverallRating; if (rating >= $scope.ratingLimit || $scope.brand === 'velocity' || $scope.country === 'tw' || $scope.country === 'hk') { $scope.items.push(item); $scope.getAlternativeProduct(item, $scope.items.length - 1); } }); if ($scope.items.length < 1) { $scope.dataReady = false; $scope.dataEmpty = true; } $scope.setPagination(); } }); }; // Get alternative product for out of stock products $scope.getAlternativeProduct = function(item, index) { if(item.product.inventoryInfo && item.product.inventoryInfo.summaryAvailabilityStatus === 'in_stock') { return; } api.alternateItem.list( { itemcode: item.product.itemCode }, function() { }, function() { } ) .$promise.then(function(data) { if(data.response.relatedProducts.length > 0) { $scope.items[index].alternateItem = data.response.relatedProducts[0]; } } ); }; $scope.removeFavorite = function(itemCode, name) { api.favourites.remove( { item: itemCode }, function(successResult) { // $window._gaq.push(['_trackEvent', 'Favorites', 'Removed_Wine_Cellar', name]); dataLayer.push({ event: 'GAevent', eventCategory: 'Favorites', eventAction: 'Removed_Wine_Cellar', eventLabel: name }); // console.log('Product has been removed'); if(dataLayer[0].userLocale === 'zh_HK_LW' || dataLayer[0].userLocale === 'zh_HK_HKLW') { $scope.$broadcast( 'flashNotification::message', '已成功從「我最愛的葡萄酒」移除此酒款。' ); } else { $scope.$broadcast( 'flashNotification::message', 'The ' + $scope.fav + ' has been successfully removed from your wine cellar.' ); } if (util.country() === 'us') { favoritesHeader.updateFavs(); } }, function(errorResult) { if (errorResult.status === 422) { $scope.errorMessage = 'The product has already been added to the ' + $scope.fav + '. Sorry, We seem to be experiencing a technical issue in removing the product from favorites.'; // console.log('Product has already been added to favorites.'); } } ); }; $scope.addFavorite = function(itemCode, name, updateScreen) { api.favourites.save( { item: itemCode }, function(successResult) { // $window._gaq.push(['_trackEvent', 'Favorites', 'Added_Wine_Cellar', name]); dataLayer.push({ event: 'GAevent', eventCategory: 'Favorites', eventAction: 'Added_Wine_Cellar', eventLabel: name }); // console.log('Product has been added to '+$scope.fav); if(dataLayer[0].userLocale === 'zh_HK_LW' || dataLayer[0].userLocale === 'zh_HK_HKLW') { $scope.$broadcast( 'flashNotification::message', '已成功將此酒款加到「我最愛的葡萄酒」。' ); } else { $scope.$broadcast( 'flashNotification::message', 'The ' + $scope.fav + ' has been successfully added to your wine cellar.' ); } // console.log(updateScreen); if (updateScreen) { $scope.getRatedList(); } if (util.country() === 'us') { favoritesHeader.updateFavs(); } }, function(errorResult) { if (errorResult.status === 422) { // console.log('422 Error - Product has already been added to '+$scope.fav+'.'); $scope.errorMessage = "Sorry, we're having trouble adding this product to your " + $scope.fav + '. Either you have already added it, or we are experiencing a technical issue. Please try refreshing your browser, and if the problem persists, contact customer care.'; } if (updateScreen) { $scope.getRatedList(); } } ); }; $scope.ratingsSearch = function (item) { if ($scope.filterText == undefined) { return true; } else { if (item.product.name?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.grapeName?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.countryName?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.vintage?.indexOf($scope.filterText) !== -1) { return true; } } return false; } $scope.colorFilter = function($event, filterVal) { $('ul.nav-tabs li').removeClass('active'); $($event.target) .parent() .toggleClass('active'); $scope.filters.color = filterVal; }; // -------- PAGINATION -------- $scope.setPagination = function() { $scope.currentPage = 1; $scope.maxSize = 16; $scope.perPage = 16; }; $scope.setPage = function(pageNo) { $scope.currentPage = pageNo; }; // -------- Broadcast Events -------- $scope.previewItem = function(itemcode, $event) { if($event) { $event.preventDefault(); } $rootScope.$broadcast('quickPreview', itemcode); }; $scope.rateItem = function(itemcode, itemname, itemvintage, itemimage) { $rootScope.$broadcast('quickRate', itemcode, itemname, itemvintage, itemimage); }; // -------- INITIAL VARIABLES -------- if ($scope.dwfav) { $scope.dwfav = $scope.dwfav.split('-'); var favLength = $scope.dwfav.length - 1; var updateScreen = false; // console.log('fav' + favLength); for (var i = 0; i < favLength + 1; i++) { if (favLength == i) { updateScreen = true; } $scope.addFavorite($scope.dwfav[i], 'triggeredByEmail_' + $scope.dwfav, updateScreen); // console.log('i' + i); } } else { $scope.getRatedList(); // console.log('else'); } $scope.getBVConfig(); $scope.filters = {}; $scope.categories = ['Red', 'White', 'Rose', 'Sparkling']; } ]); wineCellarControllers.controller('quickView', [ '$scope', 'api', '$resource', 'util', '$window', '$timeout', '$http', 'bv_api_config', 'apiBv', '$q', function($scope, api, $resource, util, $window, $timeout, $http, bv_api_config, apiBv, $q) { $scope.$on('quickPreview', function(event, item) { $scope.dataLoaded = false; $scope.compliant = true; $scope.cartConfirmation = false; $scope.apiFlag = true; $scope.quickViewQty = 1; $scope.country = util.country(); $scope.userLocale = dataLayer[0].userLocale; $scope.brand = util.brand(); $scope.dataAreaId = util.dataAreaId(); $scope.brandBtn = 'btn btn-primary'; $scope.defaultBtn = 'btn btn-default'; $scope.itemCode = $scope.country === 'au' || $scope.country === 'nz' ? item.itemCode : item; $timeout(function() { $('.preview-modal').modal(); },400); if ($scope.apiFlag) { $scope.apiFlag = false; api.product .list( { itemcode: $scope.itemCode }, function(successResult) {}, function(errorResult) { $scope.errorObject = errorResult.data; $scope.compliant = false; //console.log('error status', errorResult.data); if (errorResult.data.statusCode == 422) { $scope.dataLoaded = false; $scope.compliant = false; dataLayer.push({ event: 'GAevent', eventCategory: 'Quick View', eventAction: 'Click', eventLabel: 'Out of Stock / Non-Compliant' }); $scope.preview = item; } } ) .$promise.then(function(data) { $scope.skus = []; $scope.dataLoaded = true; //Check Wine Availability Status if (!data.response.inventoryInfo || !data.response.inventoryInfo.summaryAvailabilityStatus) { $scope.compliant = false; } else { $scope.compliant = true; } $scope.apiFlag = true; $scope.preview = data.response; if ($scope.country !== 'us') { //Keep old code for UK angular.forEach(data.response.skus, function(item) { if (item.listPrice == item.salePrice) { // no savings item.salePrice = 'null'; } else { item.savings = item.listPrice - item.salePrice; } if (item.numberOfBottles >= 2) { item.bottles = 'bottles'; } else { item.bottles = 'bottle'; } $scope.skus.push(item); }); } if ($scope.country === 'us') { var skuCopy = data.response.skus; $scope.preview.isBcCode = false; $scope.preview.isVpp = false; _.each($scope.preview.skus, function(item) { if (item.listPrice == item.salePrice) { // no savings item.salePrice = 'null'; } else { item.savings = item.listPrice - item.salePrice; } if (item.numberOfBottles >= 2) { item.bottles = 'bottles'; } else { item.bottles = 'bottle'; } if (item.itemCode[0] == 'B' || item.itemCode[0] == 'C') { $scope.preview.isBcCode = true; } if (item.vppApplier) { $scope.preview.isVpp = true; } $scope.skus.push(item); }); if (!$scope.preview.isBcCode) { var newItem1 = angular.copy($scope.skus[0]); var newItem2 = angular.copy($scope.skus[0]); var VPP = newItem2.vppPrice * 12; var SPP = newItem2.salePricePerBottle * 12; var VPPSale = SPP - VPP; // On the fly 6 bottle setup newItem1.numberOfBottles = 6; newItem1.bottles = 'bottles'; newItem1.listPrice = newItem1.salePricePerBottle * 6; $scope.skus.push(newItem1); // On the fly 12 bottle setup (Depends on VPP Flag) newItem2.numberOfBottles = 12; newItem2.bottles = 'bottles'; newItem2.listPrice = SPP; newItem2.salePrice = $scope.preview.isVpp ? VPP : 'null'; newItem2.savings = $scope.preview.isVpp ? VPPSale : 'null'; $scope.skus.push(newItem2); } } if ($scope.country === 'us' && data.response.mixed) { $scope.contentsReady = false; api.caseContents .list( { itemcode: $scope.preview.itemCode }, function(successResult) {}, function(errorResult) { $scope.errorObject = errorResult.data; //console.log('error status', errorResult.data); if (errorResult.data.statusCode == 422) { $scope.dataLoaded = false; $scope.compliant = false; } } ) .$promise.then(function(data) { $scope.dataLoaded = true; $scope.contentsReady = true; $scope.compliant = true; $scope.preview.caseContents = data.response.contentProducts; }); } angular.element('.preview-modal input:eq(0)').prop('checked', true); dataLayer.push({ event: 'GAevent', eventCategory: 'Quick View', eventAction: 'Click', eventLabel: 'Launch' }); }); } }); // -------- Swipe Navigation-------- $scope.next = function() { $scope.nextSlide(); }; $scope.prev = function() { $scope.prevSlide(); }; // -------- Add to cart -------- $scope.addToCart = function(qty) { var item = $('input[name=itemSku]:checked').val() || $('input[name=itemSku]').val(); qty = qty == 'override' ? $('input[name=itemSku]:checked').data('qty') : qty; if ($scope.country === 'uk') { var cartUrl; if ($scope.dataAreaId === 'UK') { cartUrl = api.cartUK.add; } else { cartUrl = api.cartLWM.add; } cartUrl( { item: item, qty: qty }, function(successResult) {}, function(errorResult) { var msg = errorResult.data.statusMessage; $scope.$broadcast('cartNotification::message', msg); } ).$promise.then(function(response) { // $scope.cartAdded = true; $scope.cart = response; $scope.cartConfirmation = true; var getCartUrl = '/api/cart/list'; $.ajax({ type: 'GET', url: getCartUrl, success: function(data) { console.log(data.response); $('.js-get-bottles').text(data.response.numBottles); var savings = data.response.orderPriceInfo.savings; var savingsFormat = savings.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); var total = data.response.orderPriceInfo.rawSubtotal; var totalFormat = total.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); $('.js-mini-cart-total').text('£' + totalFormat); $('.js-mini-cart-savings').text('Saving £' + savingsFormat); }, error: function() {} }); }); } else { api.cartUS .add( { item: item, qty: qty }, function(successResult) {}, function(errorResult) { //console.log('error', errorResult); //$scope.$broadcast('cartNotification::message',"The "+item+" cannot be added to your cart. Please try again or call customer service." ); } ) .$promise.then(function(response) { //console.log('success',response); // $scope.cartAdded = true; dataLayer.push({ event: 'GAevent', eventCategory: 'Quick View', eventAction: 'Click', eventLabel: 'Add to Cart' }); $scope.cart = response; $scope.cartConfirmation = true; //$scope.$broadcast('cartNotification::message',"The "+item+" has been successfully added to your cart." ); var getCartUrl = '/api/cart/list'; $.ajax({ type: 'GET', url: getCartUrl, success: function(data) { //console.log(data.response); $('.items').text(data.response.numItems + ' items'); var total = data.response.orderPriceInfo.rawSubtotal; var totalFormat = total.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); $('.total').text('$' + totalFormat); if ( ($scope.country === 'au' || $scope.country === 'nz') && $scope.brand !== 'vws' && $scope.country !== 'tw' && $scope.country !== 'hk' ) { window.miniCart.updateCartDom(data, false); } }, error: function() {} }); }); } }; // Quick Rate Modal $scope.$on('quickRate', function(event, itemCode, itemName, itemVintage, itemImage) { $scope.reviewSuccess = false; $scope.reviewSubmitSuccess = false; $scope.favoriteSubmitSuccess = false; $scope.dislikeSubmitSuccess = false; $scope.submitForm = false; $scope.errorContainer = false; $scope.loading = false; $scope.dataEnabled = true; $scope.rating = 0; $scope.reviewText = ''; $scope.clickValue = 0; console.log($scope.clickValue); $scope.actionDislike = false; $scope.actionFavorite = false; // Reset init to false $scope.initFavorite = false; $scope.initDislike = false; // Get Item information from Cellar View $scope.itemName = itemName; $scope.itemCode = itemCode; $scope.itemImage = itemImage; $scope.itemVintage = itemVintage; $scope.nickNameError = false; $scope.ratingRequired = false; $scope.reviewNicknameRequired = false; var review = { config: { starRating: 0, itemCode: itemCode, itemName: itemName, itemImage: itemImage, statusMessage: '', bvURL: '', passkey: '', apiVersion: 5.4, userId: pageLayer[0].vid, data: [], submissionErrors: [], fieldErrors: [], userDetails: [], UserNickname: '', favorite: '', dislike: '', formData: [] } }; $scope.getBVConfig = function() { var environment = util.env(); var currentBrand = util.brand(); var currentCountry = util.country(); console.log('env', environment); if (environment === 'uat' || environment === 'webdev06') { review.config.passkey = bv_api_config.staging[currentCountry][currentBrand]; review.config.bvURL = 'stg.api.bazaarvoice.com'; } else { review.config.passkey = bv_api_config.production[currentCountry][currentBrand]; review.config.bvURL = 'api.bazaarvoice.com'; } console.log('ratings', $scope.rating); }; $scope.getUser = function() { // Get BV User apiBv.user .list( { bvUrl: review.config.bvURL, passKey: review.config.passkey, apiVersion: review.config.apiVersion, userId: review.config.userId }, function(successResult) {}, function(errorResult) { $scope.errorObject = errorResult.data; console.log('error status', errorResult.data); } ) .$promise.then(function(data) { console.log('user', data); review.config.userDetails = data.Results; $scope.setUserNickname(); }); console.log('ratings', $scope.rating); }; $scope.getFavorites = function() { $scope.isFavorite = false; api.favourites .list( {}, function(successResult) {}, function(errorResult) { if (errorResult.status === 405 || errorResult.status === 500 || errorResult.status === 404) { //console.log('500 - 405 error'); } } ) .$promise.then(function(data) { // Filters by match var responseFiltered = _.filter(data.response.userItems, function(obj) { return obj.product.itemCode == review.config.itemCode; }); // console.log('favorite', responseFiltered.length); if (responseFiltered.length > 0) { // init enabled $scope.initFavorite = true; $scope.userFavorite = true; $scope.userDislike = false; $scope.favClass = 'fa fa-heart'; $scope.likeClass = 'fa fa-thumbs-o-down'; } else { $scope.userFavorite = false; $scope.favClass = 'fa fa-heart-o'; } }); }; $scope.getDislikes = function() { $scope.isDislike = false; api.dislike .list( {}, function(successResult) { // console.log('success'); }, function(errorResult) { // console.log('error', errorResult); if (errorResult.status === 405 || errorResult.status === 500 || errorResult.status === 404) { //console.log('500 - 405 error'); } } ) .$promise.then(function(data) { // Filters by match var responseFiltered = _.filter(data.response.userItems, function(obj) { return obj.product.itemCode == review.config.itemCode; }); // console.log('dislike', responseFiltered.length); if (responseFiltered.length > 0) { // init enabled $scope.initDislike = true; $scope.userDislike = true; $scope.userFavorite = false; $scope.favClass = 'fa fa-heart-o'; $scope.likeClass = 'fa fa-thumbs-down'; } else { $scope.userDislike = false; $scope.likeClass = 'fa fa-thumbs-o-down'; } $('.rating-modal').modal(); }); }; $scope.checkCharacters = function() { if (/^[a-zA-Z0-9]*$/.test($scope.reviewNickname)) { $scope.nickNameError = false; } else { $scope.nickNameError = true; } if ($scope.reviewNickname.length) { $scope.reviewNicknameRequired = false; } else { $scope.reviewNicknameRequired = true; } }; $scope.setUserNickname = function() { //console.log('username object', review.config.userDetails); if (typeof sessionStorage.bv_nickname !== 'undefined') { //if (localStorage.bv_nickname != 'undefined'){ console.log('sessionStorage', sessionStorage.bv_nickname); $scope.reviewNickname = sessionStorage.bv_nickname; $scope.nickName = true; } else if (review.config.userDetails[0]) { console.log('BV nickname', review.config.userDetails[0].UserNickname); $scope.reviewNickname = review.config.userDetails[0].UserNickname; $scope.nickName = true; } else if (typeof review.config.userDetails != 'undefined') { console.log('No nickname set'); $scope.reviewNickname = ''; } }; $scope.submitRating = function() { localStorage.setItem('bv_nickname', $scope.reviewNickname); if ($scope.rating == 0) { $scope.ratingRequired = true; } if (!$scope.reviewNickname.length) { $scope.reviewNicknameRequired = true; } else if ($scope.nickNameError) { $scope.nickNameError = true; } if (!$scope.ratingRequired && !$scope.reviewNicknameRequired && !$scope.nickNameError) { $scope.loading = true; $scope.submitForm = true; $scope.errorContainer = false; // // Submit BV Rating apiBv.rating .add( { passKey: review.config.passkey, apiVersion: review.config.apiVersion, bvUrl: review.config.bvURL, itemCode: review.config.itemCode, rating: $scope.rating, // recommend: 'true', description: $scope.reviewText, title: '', username: $scope.reviewNickname, userId: review.config.userId, userEmail: $scope.reviewEmail }, function(successResult) { // console.log('successResult', successResult); // Hide Submit button and show loading bar... }, function(errorResult) { $scope.errorObject = errorResult.data; // console.log('error status', errorResult.data); } ) .$promise.then(function(data) { // console.log('data', data); if (data.HasErrors == true) { review.config.submissionErrors = data.Errors; if ( review.config.submissionErrors.length && review.config.submissionErrors[0].Code == 'ERROR_PARAM_INVALID_API_KEY' ) { review.config.statusMessage = [ "Thanks for coming to write a review - we're having a small technical issue, but it's being fixed right now. Sorry for the inconvenience - and please check back soon as your review really matters to us." ]; $scope.processError(review.config.statusMessage); } else { review.config.fieldErrors = data.FormErrors.FieldErrors; review.config.statusMessage = !$.isEmptyObject(review.config.fieldErrors) ? $scope.getFieldErrors() : $scope.getSubmissionErrors(); $scope.processError(review.config.statusMessage); if ( review.config.statusMessage == 'Your nickname has already been taken by another reviewer. Please choose a different one.' ) { $scope.nickName = false; $scope.nickNameDupe = true; } } } else { // Process Favorites / Dislikes $scope.processSuccess(); dataLayer.push({ event: 'GAevent', eventCategory: 'Quick Rate', eventAction: 'Click', eventLabel: 'Rating/Review Submitted Success' }); } }); } }; $scope.getFieldErrors = function() { var errors = []; _.each(review.config.fieldErrors, function(obj) { var msg = obj.Message; errors.push(msg); }); // create a loop to go through all errors; return errors; }; // New Function inside the review object literal $scope.getSubmissionErrors = function() { review.config.statusMessage = 'You have already reviewed this wine!'; var errors = [review.config.statusMessage]; console.log('errors', errors); dataLayer.push({ event: 'GAevent', eventCategory: 'Quick Rate', eventAction: 'Errors', eventLabel: errors }); // create a loop to go through all errrors; return errors; }; $scope.processError = function() { $scope.errors = review.config.statusMessage; $scope.errorContainer = true; $scope.loading = false; $scope.submitForm = false; }; $scope.processSuccess = function() { var addFavorite = function() { return api.cellar.save( { list: 'favourites', item: review.config.itemCode }, function(successResult) {}, function(errorResult) {} ); }; var removeFavorite = function() { return api.cellar.del( { list: 'favourites', item: review.config.itemCode }, function(successResult) {}, function(errorResult) {} ); }; var addDislike = function() { return api.cellar.save( { list: 'donotsenditem', item: review.config.itemCode }, function(successResult) {}, function(errorResult) {} ); }; var removeDislike = function() { return api.cellar.del( { list: 'donotsenditem', item: review.config.itemCode }, function(successResult) {}, function(errorResult) {} ); }; var favoriteSuccess = function() { $scope.reviewSubmitSuccess = true; $scope.favoriteSubmitSuccess = true; $scope.submitForm = true; $scope.errors = false; }; var dislikeSuccess = function() { $scope.reviewSubmitSuccess = true; $scope.dislikeSubmitSuccess = true; $scope.submitForm = true; $scope.errors = false; }; if ($scope.initFavorite == true && $scope.userDislike == true) { // Remove favorite, Add dislike console.log('Remove favorite, Add dislike'); removeFavorite() .$promise.then(addDislike) .then(dislikeSuccess); dataLayer.push({ event: 'GAevent', eventCategory: 'Quick Rate', eventAction: 'Click', eventLabel: 'NotForMe_Add' }); dataLayer.push({ event: 'GAevent', eventCategory: 'Quick Rate', eventAction: 'Click', eventLabel: 'Favorite_Remove' }); } else if ($scope.initDislike == true && $scope.userFavorite == true) { // Remove favorite, Add dislike console.log('Remove dislike, Add favorite'); removeDislike() .$promise.then(addFavorite) .then(favoriteSuccess); dataLayer.push({ event: 'GAevent', eventCategory: 'Quick Rate', eventAction: 'Click', eventLabel: 'NotForMe_Remove' }); dataLayer.push({ event: 'GAevent', eventCategory: 'Quick Rate', eventAction: 'Click', eventLabel: 'Favorite_Add' }); } else if ($scope.initFavorite == false && $scope.initDislike == false && $scope.userFavorite == true) { // Remove favorite, Add dislike console.log('No init, Add favorite'); addFavorite().$promise.then(favoriteSuccess); dataLayer.push({ event: 'GAevent', eventCategory: 'Quick Rate', eventAction: 'Click', eventLabel: 'Favorite_Add' }); } else if ($scope.initFavorite == false && $scope.initDislike == false && $scope.userDislike == true) { // Remove favorite, Add dislike console.log('No init, Add dislike'); addDislike().$promise.then(dislikeSuccess); dataLayer.push({ event: 'GAevent', eventCategory: 'Quick Rate', eventAction: 'Click', eventLabel: 'NotForMe_Add' }); } else if ( ($scope.initFavorite == false && $scope.userDislike == false) || ($scope.initDislike == false && $scope.userFavorite == false) ) { // Ignore favorite, Ignore dislike console.log('Ignore favorite, Ignore dislike'); $scope.reviewSubmitSuccess = true; $scope.reviewSuccess = true; $scope.submitForm = true; $scope.errors = false; } else if ( ($scope.initDislike == true && $scope.userFavorite == false) || ($scope.initFavorite == true && $scope.userDislike == false) ) { // Ignore favorite, Ignore dislike console.log('Ignore favorite, Ignore dislike'); $scope.reviewSubmitSuccess = true; $scope.reviewSuccess = true; $scope.submitForm = true; $scope.errors = false; } }; $scope.showModal = function() { $('.rating-modal').modal(); }; // Init $scope.getBVConfig(); $scope.getUser(); //$scope.getProduct(); $scope.getFavorites(); $scope.getDislikes(); }); } ]); wineCellarControllers .controller('recommendationsController', [ '$scope', '$rootScope', 'api', '$resource', 'util', 'bv_config', '$state', function($scope, $rootScope, api, $resource, util, bv_config, $state) { $scope.tallestElement = 0; $scope.items = []; $scope.dataReady = false; $scope.dataEmpty = false; $scope.loadingStatusMessage = true; $scope.loadingErrorMessage = false; $scope.loading = true; $scope.orderProp = '-userItemDetails.sortPriority'; $scope.cartAdded = false; $scope.brand = util.brand(); $scope.phone = dataLayer[0].brandPhone; $scope.country = util.country(); $scope.userLocale = dataLayer[0].userLocale; $scope.brandBtn = 'btn btn-primary'; $scope.defaultBtn = 'btn btn-default'; $scope.showCb = false; $scope.promoCode = getParam('dw_mwcPromo') || 'recommendations'; // Used for MWC LP Promotions $scope.maxSize = cellarOverrides.limit || 40; $scope.overrides = { showHeader: cellarOverrides.showHeader == false ? false : true, showMixed: cellarOverrides.showMixed == false ? false : true, showBrandRec: cellarOverrides.showBrandRec == false ? false : true, fullScreen: getParam('dw_mwcPromo') }; // Load Favourites from API - Attach data to view $scope.getRecommendations = function() { api.recommendations .list( {}, function(successResult) { //console.log('success'); }, function(errorResult) { //console.log('error', errorResult); if (errorResult.status === 405 || errorResult.status === 500 || errorResult.status === 404) { //console.log('500 - 405 error'); } $scope.loadingStatusMessage = false; $scope.loadingErrorMessage = true; $scope.loading = false; } ) .$promise.then(function(data) { if (data.response.itemListInfo.numberOfItems === 0) { $scope.getMixedRecommendations(); } else { $scope.recommendations = data.response.userItems; // Removes Mixed Cases var itemList = _.filter($scope.recommendations, function(obj) { return obj.product.mixed != true; }); // Removes Brand Recommendations if (!$scope.overrides.showBrandRec) { itemList = _.filter(itemList, function(obj) { return obj.userItemDetails.recommendationTypeId != 100; }); } angular.forEach(itemList, function(item) { item.color = item.product.colourId; item.longName = item.product.name + ' ' + item.product.vintage; item.mixed = item.product.mixed; $scope.items.push(item); }); $scope.items = $scope.items.slice(0, $scope.maxSize); //Check to show CB links if ($scope.items.length >= 4) { $scope.showCb = true; } if ($scope.overrides.showMixed) { $scope.getMixedRecommendations(); } else { $scope.dataReady = true; $scope.dataEmpty = false; $scope.loading = false; $scope.loadingStatusMessage = false; } } }); }; $scope.getMixedRecommendations = function() { api.recommendations .list( { mixed: 'mixed' }, function(successResult) { //console.log('success'); }, function(errorResult) { //console.log('error', errorResult); if (errorResult.status === 405 || errorResult.status === 500 || errorResult.status === 404) { //console.log('500 - 405 error'); } $scope.loadingStatusMessage = false; $scope.loadingErrorMessage = true; $scope.loading = false; } ) .$promise.then(function(data) { if (data.response.itemListInfo.numberOfItems === 0 && $scope.items.length === 0) { $scope.loadingStatusMessage = false; $scope.dataReady = false; $scope.loading = false; $scope.dataEmpty = true; } else { $scope.dataReady = true; $scope.dataEmpty = false; $scope.loading = false; $scope.loadingStatusMessage = false; $scope.mixedRecommendations = data.response.userItems; $scope.mixedRecommendations = _.filter($scope.mixedRecommendations, function(item) { return item.userItemDetails.sortPriority > -1; }); angular.forEach($scope.mixedRecommendations, function(item) { item.color = item.product.colourId || ''; item.longName = item.product.name + ' ' + item.product.vintage; item.mixed = item.product.mixed; $scope.items.push(item); }); } }); }; // -------- Broadcast Events -------- $scope.previewItem = function(itemcode, $event) { if($event) { $event.preventDefault(); } $rootScope.$broadcast('quickPreview', itemcode); if ( $scope.country === 'au' || $scope.country === 'nz' ) { dataLayer.push({ event: 'GAevent', eventCategory: 'Recommendations', eventAction: 'Click', eventLabel: 'Order Now' }); } }; // -------- Add to cart -------- $scope.addToCart = function(qty) { var item = $('input[name=itemSku]:checked').val(); api.cart .add( { item: item, qty: qty }, function(successResult) {}, function(errorResult) { //console.log('error', errorResult); } ) .$promise.then(function(response) { //console.log('success',response); // $scope.cartAdded = true; $scope.cart = response; $scope.$broadcast( 'cartNotification::message', 'The ' + item + ' has been successfully added to your cart. Total Cart Items:' + response.numItems ); }); }; $scope.recommendationsSearch = function (item) { if ($scope.filterText == undefined) { return true; } else { if (item.product.name?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.grapeName?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.countryName?.toLowerCase().indexOf($scope.filterText.toLowerCase()) !== -1 || item.product.vintage?.indexOf($scope.filterText) !== -1) { return true; } } return false; } // -------- Color Filter -------- $scope.colorFilter = function($event, filterVal) { $('ul.nav-tabs li').removeClass('active'); $($event.target) .parent() .toggleClass('active'); $scope.filters.mixed = filterVal == '' ? '' : false; $scope.filters.mixed = filterVal == 'mixed' ? true : $scope.filters.mixed; $scope.filters.color = filterVal == 'mixed' ? '' : filterVal; }; $scope.oneClickCb = function() { dataLayer.push({ event: 'GAevent', eventCategory: 'Account', eventAction: 'Advice_Rec_Navigation', eventLabel: 'Casebuilder_OneClickCase_Launch' }); }; // -------- INITIAL VARIABLES -------- // $scope.brand = util.brandInfo(util.brand()); $scope.getRecommendations(); $scope.filters = {}; $scope.categories = ['Red', 'White', 'Rose']; $scope.winefilters = { newWine: true, rated: true, favorites: true, purchased: true, preferences: true }; } ]) .filter('winetype', function() { return function(items, winefilters) { var filterArr = []; var out = []; angular.forEach(winefilters, function(value, key) { // If Filter is True, convert to number & add to array. if (value === true) { var x = 0; switch (key) { case 'preferences': x = 40; filterArr.push('41'); filterArr.push('42'); filterArr.push('43'); filterArr.push('44'); filterArr.push('45'); filterArr.push('46'); filterArr.push('47'); filterArr.push('48'); filterArr.push('49'); break; case 'purchased': x = 30; break; case 'favorites': x = 20; break; case 'rated': x = 10; break; case 'newWine': x = 100; break; } filterArr.push(x); } }); var len = filterArr.length; angular.forEach(items, function(value, key) { var wineMatch = false; for (var x = 0; x < len; x++) { if (value.userItemDetails.recommendationTypeId == filterArr[x]) { wineMatch = true; } } if (wineMatch) { out.push(value); } }); return out; }; }); wineCellarControllers.directive('equalize', function($window, $timeout) { return { restrict: 'A', link: function(scope, element, attr) { scope.setTallest = function() { $timeout(function() { //this code will execute right after ng-repeat rendering has been completed var currentElement = angular.element('.wine-grid-container'); angular.element($window).on('resize', onResize); function onResize() { // Loop through each element angular.forEach(currentElement, function(value, key) { value.style.cssText = ''; var thisHeight = angular.element(value).height(); if (thisHeight > scope.tallestElement) { scope.tallestElement = thisHeight; } }); // Apply height to all elements if (scope.country !== 'us') { currentElement.height(scope.tallestElement); } } onResize(); }, 500); }; if (scope.$last === true) { scope.setTallest(); } scope.$watch('items', function(oldVal, newVal) { if (newVal.length) { scope.setTallest(); } }); } }; }); /* ==== All functions should be setup as an object literal to help with namespacing / prevent global vars */ 'use strict'; /* App Module */ var wineCellarDirectives = angular.module('wineCellarDirectives', []); wineCellarDirectives.directive('fallbackSrc', function() { return { link: function postLink(scope, iElement, iAttrs) { iElement.bind('error', function() { angular.element(this).attr('src', iAttrs.fallbackSrc); }); } }; }); wineCellarDirectives.directive('flashNotification', function($animate, $timeout) { return { restrict: 'E', scope: {}, link: function postLink(scope, iElement, iAttrs) { scope.$on('flashNotification::message', function(e, message) { var messageElement = angular.element('
'); messageElement.text(message); iElement.append(messageElement); $timeout(function() { $animate.leave(messageElement); }, 1500); // Can customise time }); } }; }); wineCellarDirectives.directive('cartNotification', function($animate, $timeout) { return { restrict: 'E', scope: {}, link: function postLink(scope, iElement, iAttrs) { scope.$on('cartNotification::message', function(e, message) { var messageElement = angular.element(''); messageElement.text(message); iElement.append(messageElement); $timeout(function() { $animate.leave(messageElement); }, 2500); // Can customise time }); } }; }); wineCellarDirectives.directive('starRating', function() { return { restrict: 'A', template: ' ', scope: { ratingValue: '=' }, link: function(scope, elem, attrs) { scope.Ulclasses = ''; scope.liclasses = ''; if (pageLayer[0].brand === 'vws' || pageLayer[0].country === 'tw' || pageLayer[0].country === 'hk') { scope.Ulclasses = ' d-flex justify-content-start align-items-center'; scope.liclasses = ' mr-7'; } scope.stars = []; for (var i = 0; i < scope.ratingValue; i++) { scope.stars.push({}); } } }; }); wineCellarDirectives.directive('starRatingHover', function() { return { restrict: 'A', template: ' ', scope: { ratingValue: '=' }, link: function(scope, elem, attrs) { scope.stars = []; for (var i = 0; i < scope.ratingValue; i++) { scope.stars.push({}); } } }; }); wineCellarDirectives.directive('avgStarRating', function() { return { restrict: 'A', template: ' ', scope: { ratingValue: '=' }, link: function(scope, elem, attrs) { var updateStars = function(value) { scope.stars = []; var ratingDecimal = (value % 1).toFixed(1); var ratingWhole = Math.floor(value); for (var i = 0; i <= 4; i++) { if (i <= ratingWhole - 1) { scope.starClass = 'fa fa-star'; } else if (ratingDecimal >= 0.5) { scope.starClass = 'fa fa-star fa-star-half-full'; ratingDecimal = 0.0; } else { scope.starClass = 'fa fa-star fa-star-o'; } scope.stars.push({ starClass: scope.starClass }); } }; scope.$watch('ratingValue', function(newVal, oldVal) { if (newVal) { updateStars(newVal); } }); } }; }); wineCellarDirectives.directive('toggleFavorites', function() { return { scope: true, restrict: 'E', replace: true, template: '', link: function(scope, element, attrs) { element.bind('click', function() { element.toggleClass('fa-heart-o'); }); } }; }); wineCellarDirectives.directive('toggleDislike', function() { return { scope: true, restrict: 'E', replace: true, template: '', link: function(scope, element, attrs) { element.bind('click', function() { element.toggleClass('fa-ban-active'); }); } }; }); wineCellarDirectives.directive('favorites', function() { return { template: '', scope: { userFavorite: '=enabled', userDislike: '=disabled', likeClass: '=', favClass: '=' }, restrict: 'E', controller: function($scope) { $scope.toggle = function() { $scope.userFavorite = !$scope.userFavorite; $scope.initFavorite = false; if ($scope.userFavorite === false) { $scope.favClass = 'fa fa-heart-o'; $scope.userDislike = false; } else if ($scope.userFavorite === true) { $scope.favClass = 'fa fa-heart'; $scope.likeClass = 'fa fa-thumbs-o-down'; $scope.userDislike = false; } }; } }; }); wineCellarDirectives.directive('dislikes', function() { return { template: '', scope: { userFavorite: '=disabled', userDislike: '=enabled', likeClass: '=', favClass: '=' }, restrict: 'E', controller: function($scope) { $scope.toggle = function() { $scope.userDislike = !$scope.userDislike; $scope.initDislike = !$scope.initDislike; if ($scope.userDislike === false) { $scope.likeClass = 'fa fa-thumbs-o-down'; $scope.userFavorite = false; } else if ($scope.userDislike === true) { $scope.likeClass = 'fa fa-thumbs-down'; $scope.favClass = 'fa fa-heart-o'; $scope.userFavorite = false; } }; } }; }); wineCellarDirectives.directive('starsRating', function() { return { restrict: 'A', template: ' ', scope: { ratingValue: '=', max: '=', onRatingSelected: '&', clickValue: '=', ratingRequired: '=' }, link: function(scope, elem, attrs) { var updateStars = function() { scope.stars = []; for (var i = 0; i < scope.max; i++) { scope.stars.push({ filled: i < scope.ratingValue }); switch (scope.ratingValue) { case 1: scope.ratingValueTxt = 'Poor'; break; case 2: scope.ratingValueTxt = 'Fair'; break; case 3: scope.ratingValueTxt = 'Average'; break; case 4: scope.ratingValueTxt = 'Good'; break; case 5: scope.ratingValueTxt = 'Excellent'; break; default: scope.ratingValueTxt = ''; break; } } }; //Click Stars scope.toggle = function(index) { scope.ratingValue = index + 1; scope.onRatingSelected({ rating: index + 1 }); scope.clickValue = scope.ratingValue; }; //Hover Stars scope.fillStars = function(index) { scope.ratingValue = index + 1; scope.onRatingSelected({ rating: index + 1 }); }; //Mouse Leave Goes Back To Clicked Star scope.emptyStars = function(index) { scope.ratingValue = scope.clickValue; }; scope.starClass = function(/** Star */ star, /** Integer */ idx) { var starClass = 'fa-star-o'; if (star.filled) { starClass = 'fa-star'; } return starClass; }; scope.$watch('ratingValue', function(oldVal, newVal) { if (newVal) { scope.ratingRequired = false; updateStars(); } }); } }; }); wineCellarDirectives.directive('paginationViewResults', function() { return { restrict: 'E', template: '(Viewing {{firstRec}} - {{lastRec}} of {{totalResults}} Wines)', replace: true, scope: { perPage: '=', totalItems: '=', currentPage: '=' }, link: function(scope, elem, attrs) { scope.setResults = function(page) { var totalPerPage = scope.perPage * page; scope.firstRec = scope.perPage * page - scope.perPage + 1; scope.lastRec = totalPerPage > scope.totalResults ? scope.totalResults : totalPerPage; }; scope.$watch('totalItems', function(newVal, oldVal) { if (newVal) { scope.totalResults = newVal; scope.setResults(scope.currentPage); } }); scope.$watch('currentPage', function(newVal, oldVal) { if (newVal) { scope.setResults(newVal); } }); } }; }); //Control label next to the total wines value wineCellarDirectives.directive('totalWineLabel', function() { return { restrict: 'E', template: '{{wineTxtLabel}}', replace: true, scope: { totalItems: '=' }, link: function(scope) { /* Check if the total number of items changed if it doesn't update label */ scope.$watch('totalItems', function(newVal) { if (newVal) { if (newVal === 1) { scope.wineTxtLabel = 'wine'; } else { scope.wineTxtLabel = 'wines'; } } }); } }; }); 'use strict'; /* App Module */ var wineCellarFilters = angular.module('wineCellarFilters', []); wineCellarFilters.filter('favorite', function() { return function(input) { return input ? 'fa-heart' : 'fa-heart-o'; }; }); wineCellarFilters.filter('notes', function() { return function(input) { return input ? 'fa-pencil-square-o' : 'fa-pencil-square-o'; }; }); wineCellarFilters.filter('offset', function() { return function(input, start) { start = parseInt(start, 10); return input.slice(start); }; }); wineCellarFilters.filter('truncate', function() { return function(text, length, end) { if (isNaN(length)) length = 10; if (end === undefined) end = '...'; if (text.length <= length || text.length - end.length <= length) { return text; } else { return String(text).substring(0, length - end.length) + end; } }; }); wineCellarFilters.filter('startFrom', function() { return function(input, start) { start = +start; //parse to int return input.slice(start); }; }); 'use strict'; var apiServices = angular.module('apiServices', []); apiServices.factory('api', function($resource) { return { cartUS: $resource( '/api/cart/:action/:itemcode/:item/:qty?method=:method', {}, { list: {method: 'GET', params: {action: 'list'}, isArray: false}, add: {method: 'PUT', params: {item: '@item', qty: '@qty', itemcode: 'itemcode'}}, update: {method: 'PUT', params: {item: '@item', qty: '@qty', method: 'set', itemcode: 'itemcode'}}, remove: {method: 'DELETE', params: {item: '@item', itemcode: 'itemcode'}}, del: {method: 'PUT', params: {action: 'delete', item: '@item', itemcode: 'itemcode'}} } ), cartLWM: $resource( '/api/cart/:action/:salescode/:item/:qty', {}, { list: {method: 'GET', params: {action: 'list'}, isArray: false}, add: {method: 'PUT', params: {item: '@item', qty: '@qty', salescode: 'salescode'}}, remove: {method: 'DELETE', params: {item: '@item', salescode: 'salescode'}}, del: {method: 'PUT', params: {action: 'delete', item: '@item', salescode: 'itemcode'}} } ), cartUK: $resource( '/api/cart/:action/:itemcode/:item/:qty', {}, { list: {method: 'GET', params: {action: 'list'}, isArray: false}, add: {method: 'PUT', params: {item: '@item', qty: '@qty', itemcode: 'itemcode'}}, remove: {method: 'DELETE', params: {item: '@item', itemcode: 'itemcode'}}, del: {method: 'PUT', params: {action: 'delete', item: '@item', itemcode: 'itemcode'}} } ), cartBatch: $resource( '/api/cart/:action/itemcode', {}, { add: {method: 'POST'} } ), cellar: $resource( '/api/user/:list/:action/:item', {}, { list: {method: 'GET', params: {list: '@list', action: 'list'}, isArray: false}, save: {method: 'PUT', params: {list: '@list', item: '@item'}}, remove: {method: 'DELETE', params: {list: '@list', item: '@item'}}, del: {method: 'PUT', params: {list: '@list', action: 'delete', item: '@item'}} } ), favourites: $resource( '/api/user/favourites/:action/:item', {}, { list: {method: 'GET', params: {action: 'list'}, isArray: false}, save: {method: 'PUT', params: {item: '@item'}}, remove: {method: 'DELETE', params: {item: '@item'}}, del: {method: 'PUT', params: {action: 'delete', item: '@item'}} } ), dislike: $resource( ' /api/user/donotsenditem/:action/:item', {}, { list: {method: 'GET', params: {action: 'list'}, isArray: false}, add: {method: 'PUT', params: {item: '@item'}}, del: {method: 'PUT', params: {action: 'delete', item: '@item'}} } ), purchases: $resource( '/api/user/purchases/:action/', {}, { list: {method: 'GET', params: {action: 'list'}, isArray: false} } ), ratings: $resource( '/api/user/ratings/:action/', {}, { list: {method: 'GET', params: {action: 'list'}, isArray: false} } ), recommendations: $resource( '/api/user/recommendations/:action/:mixed', {}, { list: {method: 'GET', params: {action: 'list', mixed: '@mixed'}, isArray: false} } ), product: $resource( '/api/product/item/:itemcode', {}, { list: {method: 'GET', params: {itemcode: '@itemcode'}, isArray: false} } ), caseContents: $resource( '/api/product/case/:itemcode', {}, { list: {method: 'GET', params: {itemcode: '@itemcode'}, isArray: false} } ), preferences: $resource( '/api/user/preferences/:action/', {}, { list: {method: 'GET', params: {action: 'list'}, isArray: false}, add: {method: 'POST'} } ), alternateItem: $resource( '/api/product/alternateItem/:itemcode', {}, { list: {method: 'GET', params: {itemcode: '@itemcode'}, isArray: false} } ), offerlist: $resource( '/api/itemlist/:name/:locale/:companyCode', {}, { list: {method: 'GET', params: {action: 'list'}, isArray: false} } ), notes: $resource( '/php/us/tasting_notes.php?brand=:brand', {}, { list: {method: 'GET', params: {brand: '@brand'}, isArray: true} } ) }; }); 'use strict'; var apiBvServices = angular.module('apiBvServices', []); apiBvServices.factory('apiBv', function($resource) { return { product: $resource( 'https://:bvUrl/data/products.json?passkey=:passKey&apiversion=:apiVersion&filter=:ratingLimit&stats=reviews&limit=:limit', {}, { list: { method: 'GET', params: { passKey: '@passKey', apiVersion: '@apiVersion', bvUrl: '@bvUrl', limit: '@limit', ratingLimit: '@ratingLimit' }, isArray: false } } ), review: $resource( 'https://:bvUrl/data/reviews.json?passkey=:passKey&apiversion=:apiVersion&Filter=:id&stats=reviews&limit=100', {}, { list: { method: 'GET', params: { passKey: '@passKey', apiVersion: '@apiVersion', bvUrl: '@bvUrl', id: '@id' }, isArray: false } } ), rating: $resource( 'https://:bvUrl/data/submitreview.json?passkey=:passKey&apiversion=:apiVersion&ProductId=:itemCode&Action=submit&Rating=:rating&IsRecommended=:recommend&ReviewText=:description&Title=:title&UserId=:userId&UserNickname=:username&UserEmail=:userEmail', {}, { add: { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, params: { passKey: '@passKey', apiVersion: '@apiVersion', bvUrl: '@bvUrl', itemCode: '@itemCode', rating: '@rating', recommend: '@recommend', description: '@description', title: '@title', username: '@username', userId: '@userId', userEmail: '@userEmail' }, isArray: false } } ), user: $resource( 'https://:bvUrl/data/authors.json?passkey=:passKey&apiversion=:apiVersion&filter=id::userId', {}, { list: { method: 'GET', params: { passKey: '@passKey', apiVersion: '@apiVersion', bvUrl: '@bvUrl', userId: '@userId' }, isArray: false } } ) }; }); var utilServices = angular.module('utilServices', []); utilServices.factory('util', function() { return { brand: function() { var brand = _.filter( [ 'zagat', 'tcmwineclub', 'natgeowine', 'virgin', 'wsjwine', 'winepeople', 'australian', 'nprwineclub', 'bhgwine', 'macyswinecellar', 'laithwaites', 'sundaytimeswineclub', 'bbcgoodfoodwineclub', 'averys', 'bawineclub', 'bawineflyer', 'bawineexplorer', 'velocity', 'directwines', 'directwinesHK' ], function(elem) { return location.host.indexOf(elem) > 0; } ); if ( brand[0] === 'tcmwineclub' || brand[0] === 'natgeowine' || brand[0] === 'nprwineclub' || brand[0] === 'bhgwine' ) { brand[0] = 'laithwaites'; } return brand[0]; }, brandInfo: function(brand) { var phoneNumber = '1-800-649-4637'; if (this.country() === 'us') { if ( brand === 'laithwaites' || brand === 'tcmwineclub' || brand === 'natgeowine' || brand === 'nprwineclub' || brand === 'bhgwine' ) { brand = 'laithwaites_us'; } } var obj = { wsjwine: { name: 'WSJwine', phone: '1-877-975-9463', shorthand: 'wsj', locale: 'en_US_WSJ' }, laithwaites_us: { name: "Laithwaite's Wine", phone: phoneNumber, shorthand: 'law', locale: 'en_US_4S' }, macyswinecellar: { name: "Macy's Wine Cellar", phone: '1-888-997-0319', shorthand: 'mcy', locale: 'en_US_MACYS' }, virgin: { name: 'Virgin Wines', phone: '1-866-426-0336', shorthand: 'vir', locale: 'en_US_Virgin' }, winepeople: { name: 'Wine People', phone: '1300 362 629', shorthand: 'wpe', locale: 'en_AU_WP' }, australian: { name: 'The Australian Wine', phone: '1300 765 021', shorthand: 'adc', locale: 'en_AU_ADC' }, velocity: { name: 'Virgin Wines Redemption store', phone: '1300 241 080', shorthand: 'vws', locale: 'en_AU_VWS' }, directwines: { name: 'Direct Wines', phone: '(02)7701-0188', shorthand: 'law', locale: 'en_TW_LAW' }, directwinesHK: { name: 'Direct Wines', phone: '8120 3826', shorthand: 'hlw', locale: 'en_HK_LW' }, laithwaites: { name: "Laithwaite's Wine", phone: '03330 148 198', shorthand: 'law', locale: 'en_GB_UKLAIT' }, sundaytimeswineclub: { name: 'Sunday Times Wine Club', phone: '03330 142 776', shorthand: 'stw', locale: 'en_GB_UKCLUB' }, averys: { name: 'Averys of Bristol', phone: '03330 148 208', shorthand: 'avy', locale: 'en_GB_AVR' }, bawineclub: { name: 'The Wine Explorer', phone: '03330 142 757', shorthand: 'ba', locale: 'en_GB_UKLAIT' }, bawineflyer: { name: 'The British Airways Wine Flyer', phone: '03330 142 759', shorthand: 'ba', locale: 'en_GB_UKLAIT' }, bawineexplorer: { name: 'The Wine Explorer', phone: '03330 142 757', shorthand: 'ba', locale: 'en_GB_UKLAIT' }, bbcgoodfoodwineclub: { name: 'BBC Good Food Wine Club', phone: '03330 148 208', shorthand: 'bbc', locale: 'en_GB_UKLAIT' } }; return obj[brand]; }, dataAreaId: function() { var dataAreaId; if (dataLayer && dataLayer[0] && dataLayer[0].dataAreaId === 'LWM') { dataAreaId = 'LWM'; } else { dataAreaId = 'UK'; } return dataAreaId; }, country: function() { if (location.host.indexOf('co.uk') > 0) { return 'uk'; } else if (location.host.indexOf('com.au') > 0) { return 'au'; } else if (location.host.indexOf('co.nz') > 0) { return 'nz'; } else if (location.host.indexOf('com.tw') > 0) { return 'tw'; } else if (location.host.indexOf('com.hk') > 0) { return 'hk'; } else { return 'us'; } }, domain: function() { return location.host; }, env: function() { var full = window.location.host; var parts = full.split('.'); return parts[0]; }, showUnlimited: function() { var freeShipProfile = pageLayer[0].fsp; var offerUnlimited = pageLayer[0].ou; if (offerUnlimited === '1' || offerUnlimited === '') { return 'standard'; } else if (offerUnlimited === '2') { return 'promotional'; } else if (offerUnlimited === '3') { return 'half-price'; } else if (freeShipProfile === 'true' || offerUnlimited === '0') { return false; } }, unlimitedInfo: function(brand, unlimitedType) { var obj = { wsjwine: { unlimited: { standard: '/product/WSJwine-1-Year-Advantage-Delivery-Membership/00034SV', promotional: '/product/WSJwine-1-Year-Unlimited-Delivery-Membership/17110UL', 'half-price': '/product/WSJwine-1-Year-Unlimited-Delivery-Membership/17111UL' } }, laithwaites: { unlimited: { standard: '/product/Laithwaites-1-Year-Unlimited-Delivery-Membership/00033SV', promotional: '/product/Laithwaites-1-Year-Unlimited-Delivery-Membership/17096UL', 'half-price': '/product/Laithwaites-1-Year-Unlimited-Delivery-Membership/17100UL' } }, virgin: { unlimited: { standard: '/product/Virgin-Wines-1-Year-Unlimited-Delivery-Membership/00035SV', promotional: '/product/Virgin-Wines-1-Year-Unlimited-Delivery-Membership/17112UL', 'half-price': '/product/Virgin-Wines-1-Year-Unlimited-Delivery-Membership/17113UL' } }, macyswinecellar: { unlimited: { standard: "/product/Macy's-1-Year-Unlimited-Delivery-Membership/00036SV", promotional: "/product/Macy's-1-Year-Unlimited-Delivery-Membership/18015UL", 'half-price': "/product/Macy's-1-Year-Unlimited-Delivery-Membership/18016UL" } } }; return obj[brand].unlimited[unlimitedType]; }, setGA: function(category, action, label) { dataLayer.push({event: 'GAevent', eventCategory: category, eventAction: action, eventLabel: label}); return {category: category, action: action, label: label}; } }; }); /* Config Module */ var wineCellarConstants = angular.module('wineCellarConstants', []); wineCellarConstants.constant('bv_config', { staging: { au: { winepeople: 'http://winepeople.ugc.bazaarvoice.com/bvstaging/3128-en_au/', virgin: 'http://reviews.virginwines.com.au/bvstaging/2511-en_au/', australian: 'http://australianwine.ugc.bazaarvoice.com/bvstaging/3127-en_au/' }, nz: { laithwaiteswine: 'http://laithwaiteswine.ugc.bazaarvoice.com/bvstaging/3129-en_us/' }, tw: { directwines: '' }, hk: { directwines: '' }, us: { laithwaiteswine: 'http://laithwaiteswine.ugc.bazaarvoice.com/bvstaging/3129-en_us/', virgin: 'http://reviews.virginwines.com/bvstaging/2511/', wsjwine: 'http://reviews.wsjwine.com/bvstaging/3131/' }, uk: { sundaytimeswineclub: '//stwc.ugc.bazaarvoice.com/bvstaging/2131-en_gb/', laithwaites: '//laithwaites.ugc.bazaarvoice.com/bvstaging/3130redes-en_gb/' } }, production: { au: { winepeople: 'http://winepeople.ugc.bazaarvoice.com/3128-en_au/', virgin: 'http://reviews.virginwines.com.au/2511-en_au/', australian: 'http://australianwine.ugc.bazaarvoice.com/3127-en_au/' }, nz: { laithwaiteswine: 'http://laithwaiteswine.ugc.bazaarvoice.com/bvstaging/3129-en_us/' }, tw: { directwines: '' }, hk: { directwines: '' }, us: { laithwaiteswine: 'http://laithwaiteswine.ugc.bazaarvoice.com/3129-en_us/', virgin: 'http://reviews.virginwines.com/2511/', wsjwine: 'http://reviews.wsjwine.com/3131/' }, uk: { sundaytimeswineclub: '//stwc.ugc.bazaarvoice.com/2131-en_gb/64093/', laithwaites: '//laithwaites.ugc.bazaarvoice.com/3130redes-en_gb/' } } }); wineCellarConstants.constant('bv_api_config', { staging: { us: { laithwaiteswine: 'skktf57raycmmd993wj9npgy', virgin: 'hzackg6b2vfcxw49ya58zju5', wsjwine: 'mhm2fyta7p9kf566vj8zpmk3', macyswinecellar: 'caBuMVWgdcOkLSZtRfXig9jJ8ynxaF6s8skNjJGcYLT5I' } }, production: { us: { laithwaiteswine: 'lmzo8bsuy3ia1ubomqcrzrktq', virgin: '3f2z1is5bk9n9iosddcx6pagf', wsjwine: '9m8wfbdu0ss2y8vtdauab5yhs', macyswinecellar: 'caWTd3SjVMMOVTkbh58qo51gTgQMilHu4oE1oePFjQE6s' } } });