(function() {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.controller('placesController',
        [
            '$scope', 'urls', 'localize', '$window', 'dates', 'locations', '$mdDialog', 'people',
            'trades', '$rootScope', '$state', 'host', 'featureToggle',
            function placesCtrl($scope,
                metUrls,
                metLocalize,
                $window,
                metDates,
                metPlaces,
                $mdDialog,
                metPeople,
                metTrades,
                $rootScope,
                $state,
                host,
                featureToggle) {
                $scope.initialize = initialize;
                $scope.loading = true;
                $scope.exportLink = '';
                $scope.dateFormat = metDates.date(true);
                $scope.dateTimeFormat = metDates.shortDateTime(true);
                $scope.placeCounts = [];
                $scope.resultsPerPage = 10;
                $scope.pageIndex = 0;
                $scope.totalPages = 0;
                $scope.currentPage = 1;
                $scope.workingCount = 0;
                $scope.allPlaceFilter = true;
                $scope.projectJobFilter = false;
                $scope.vehicleFilter = false;
                $scope.homeBaseFilter = false;
                $scope.unspecifiedFilter = false;
                $scope.typeIdFilters = [];
                $scope.toolCount = 0;
                $scope.places = [];
                $scope.people = [];
                $scope.hasInventoryItems = false;
                $scope.hasResults = false;
                $scope.hasFilters = false;
                $scope.learnMore = false;
                $scope.showLearnMore = showLearnMore;
                $scope.goToMigration = goToMigration;
                $scope.resultsPerPageOptions = [10, 25, 50];
                $scope.currentSortField = 'name';
                $scope.setSortField = setSortField;
                $scope.sortAscending = true;
                $scope.selectedPlaceId = 0;
                $scope.selectedPlace = {};
                $scope.toggleSearchContainer = toggleSearchContainer;
                $scope.clearSearch = clearSearch;
                $scope.transferReportBaseUrl = '';

                function showLearnMore() {
                    $scope.learnMore = !$scope.learnMore;
                    var lang = host.languageSegment();
                    if (lang === 'de' || lang === 'fr' || lang === 'fi') {
                        setTimeout(function () {
                            $('div#searchCard.place-info-card')[0].style.height = '280px';
                        },
                            0);
                    }
                }

                function goToMigration() {
                    $scope.learnMore = false;
                    $state.go('place-migration');
                }

                var ctrl = this;
                ctrl.searchTerm = '';

                $scope.messages = {
                    addPlaceConversational: metLocalize('commands', 'addPlaceConversational'),
                    cancel: metLocalize('commands', 'cancel'),
                    clearFilters: metLocalize('commands', 'clearFilters'),
                    delete: metLocalize('commands', 'delete'),
                    deletePlaceConfirmation: metLocalize('messages', 'deletePlaceConfirmation'),
                    deletePlaceMessage: metLocalize('messages', 'deletePlaceMessage'),
                    deletePlaceMessage_Corrected: metLocalize('messages', 'deletePlaceMessage_Corrected'),
                    homeBase: metLocalize('fieldNames', 'homeBase'),
                    noResults: metLocalize('messages', 'noResults'),
                    noResultsForFilters: metLocalize('messages', 'noResultsForFilters'),
                    projectJob: metLocalize('fieldNames', 'projectJob'),
                    unspecified: metLocalize('titles', 'unassigned'),
                    vehicle: metLocalize('fieldNames', 'vehicle'),
                    welcomeToPlaces: metLocalize('messages', 'welcomeToPlaces'),
                    welcomeToPlacesText: metLocalize('messages', 'welcomeToPlacesText'),
                    aboutProjectJob: metLocalize('messages', 'aboutProjectJob'),
                    aboutHomeBase: metLocalize('messages', 'aboutHomeBase'),
                    aboutVehicle: metLocalize('messages', 'aboutVehicle'),
                    jobProject: metLocalize('fieldNames', 'placeType_ProjectJob'),
                    add: metLocalize('commands', 'add'),
                    placeMigrationIntro: metLocalize('messages', 'placeMigrationIntro'),
                    getStarted: metLocalize('commands', 'getStarted'),
                    noTimeNowForMigration: metLocalize('messages', 'noTimeNowForMigration'),
                    categorizeYourBusines: metLocalize('messages', 'categorizeYourBusines'),
                    places: metLocalize('titles', 'places'),
                    resultsPerPage: metLocalize('messages', 'resultsPerPage'),
                    of: metLocalize('messages', 'of'),
                    aboutHomeBase_corrected: metLocalize('messages', 'aboutHomeBase_corrected'),
                    geofencingBetaTitle: metLocalize('messages', 'geofencingBetaTitle'),
                    geofencingBetaSubTitle: metLocalize('messages', 'geofencingBetaSubTitle'),
                    geofencingInOutTitle: metLocalize('messages', 'geofencingInOutTitle'),
                    geofencingInOutSubTitle: metLocalize('messages', 'geofencingInOutSubTitle'),
                    geofencingDailyNotificationTitle: metLocalize('messages', 'geofencingDailyNotificationTitle'),
                    geofencingDailyNotificationSubTitle: metLocalize('messages', 'geofencingDailyNotificationSubTitle'),
                    previous: metLocalize('messages', 'previous'),
                    next: metLocalize('messages', 'next')
                };

                // -- jstz is gotten from the jsTimezoneDetect library - no other declaration is needed
                $scope.timeZone = new jstz.determine().name();

                $scope.generate = function(baseUrl, id) {
                    var url = baseUrl + '?Id=' + id + '&timeZone=' + $scope.timeZone;
                    document.cookie = "Authorization=Bearer " + localStorage.getItem('access_token') + ";path=/";
                    $window.location.href = url;
                };

                $scope.region = "";

                $scope.collapseAll = function() {
                    _.forEach($scope.places,
                        function(place) {
                            place.isExpanded = false;
                        });
                };

                $scope.deleteImage = function(place) {
                    place.imageUrl = null;
                    place.detailEmpty = true;
                };

                $scope.clearFilters = function() {
                    ctrl.searchTerm = "";
                    $scope.allPlaceFilter = true;
                    $scope.projectJobFilter = false;
                    $scope.vehicleFilter = false;
                    $scope.homeBaseFilter = false;
                    $scope.typeIdFilters = [];
                    $scope.getPlaces();
                };

                $scope.getDivisions = function() {
                    metTrades.getAll({ includeUnspecified: true },
                        function(data) {
                            $scope.divisions = data.items;
                            _.forEach($scope.divisions, function(division) { division.selected = false });
                        });
                };

                $scope.updatePlaceCounts = function() {
                    metPlaces.counts(function(response) {
                            $scope.placeCounts = response;
                        },
                        function(error) {
                            console.log(error);
                        });
                }

                $scope.updatePlace = function(place) {                  
                    metPlaces.update(place,
                        function(response) {
                            //Removed all collapsing becuase we want to stay on the edit screen
                            place.startingAddressLine = response.addressLine;
                            place.startingCityStateZip = response.cityStateZip;
                            place.latitude = response.latitude;
                            place.longitude = response.longitude;
                            //-- if there's an address but no image then show only the address
                            if (response.addressLine || response.cityStateZip) {
                                place.detailAddress = true;
                            }
                            else if (!response.imageUrl) {
                                //-- if there's no address and no image then show icons
                                place.detailEmpty = true;
                            }
                            place.errorMessage = null;
                            $rootScope.$broadcast('update-place', response);
                        },
                        function(error) {
                            if (error.data.message) {
                                place.errorMessage = error.data.message;
                                console.log(error.data.message);
                            }
                        });
                };

                $scope.deletePlace = function(place) {
                    metPlaces.remove(place,
                        function() {
                            $scope.collapseAll();
                            $scope.getPlaces();
                        },
                        function(error) {
                            if (error.data.message) {
                                console.log(error.data.message);
                            }
                        });
                };

                $rootScope.$on("reload-places",
                    function() {
                        $scope.initialize();
                    });


                $scope.goToPage = function(pageNumber) {
                    if (pageNumber) {
                        $scope.pageIndex = pageNumber - 1;
                        $scope.currentPage = pageNumber;
                        localStorage.setItem('placesPageNumber', $scope.currentPage);
                        if (document.getElementById('places-paging-textbox')) {
                            document.getElementById('places-paging-textbox').value = pageNumber;
                        }
                        $scope.getPlaces();
                    }
                }

                $scope.goTo = function() {
                    var inputElement = document.getElementById('places-paging-textbox');
                    var pageNumber = parseInt(inputElement.value);
                    var inRange = function() {
                        return pageNumber <= $scope.totalPages && pageNumber > 0;
                    }

                    if (inRange()) {
                        $scope.goToPage(pageNumber);
                    }
                    else {
                        if (pageNumber > $scope.totalPages) {
                            inputElement.value = $scope.totalPages;
                            $scope.goToPage($scope.totalPages);
                        }
                        else {
                            inputElement.value = 1;
                            $scope.goToPage(1);
                        }
                    }
                }

                $scope.changeResultsPerPage = function(resultOption) {
                    $scope.resultsPerPage = resultOption;
                    $scope.pageIndex = 0;
                    $scope.getPlaces();
                }

                $scope.$watch('typeIdFilters',
                    function(newValue, oldValue) {
                        if (newValue !== oldValue) {
                            $scope.currentPage = 1;
                            $scope.pageIndex = 0;
                            $scope.workingCount = $scope.getWorkingCount(newValue[0]);
                        }
                    });

                $scope.getWorkingCount = function(n) {
                    if (n === 1) {
                        return $scope.placeCounts.unspecifiedCount;
                    }
                    else if (n === 2) {
                        return $scope.placeCounts.projectJobCount;
                    }
                    else if (n === 3) {
                        return $scope.placeCounts.homeBaseCount;
                    }
                    else if (n === 4) {
                        return $scope.placeCounts.vehicleCount;
                    }
                    else {
                        if ($scope.placeCounts.searchTermToolCount > 0) {
                            return $scope.placeCounts.searchTermToolCount;
                        }
                        return $scope.placeCounts.placesCount;
                    }
                }

                function getTotalPages() {
                    var wc = $scope.getWorkingCount($scope.typeIdFilters[0]);
                    $scope.workingCount = wc;
                    return Math.ceil(wc / $scope.resultsPerPage);
                }

                function resetPaging() {
                    var inputElement = document.getElementById('places-paging-textbox');
                    $scope.pageIndex = 0;
                    $scope.currentPage = 1;
                    localStorage.setItem('placesPageNumber', $scope.currentPage);
                    if (inputElement) {
                        inputElement.value = $scope.currentPage;
                    }
                }

                function setNoPlaceDisplay() {
                    var el = document.getElementById('places_new-places');
                    if (!$scope.hasResults && el) {
                        $(el).show();
                    }
                    if (!$scope.hasResults && !$scope.hasFilters && !el) {
                        window.location.href = '#';
                    }
                }

                $scope.getPlaces = function(placeId) {
                    ctrl.isLoading = true;
                    var filters = {
                        skip: getSkipTotal(),
                        take: $scope.resultsPerPage,
                        typeIds: $scope.typeIdFilters,
                        searchTerm: ctrl.searchTerm,
                        sortField: $scope.currentSortField,
                        sortDescending: !$scope.sortAscending,
                    };
                    if (placeId !== -1) {
                        filters.placeId = placeId;
                        $scope.selectedPlaceId = filters.placeId;
                    }
                    return metPlaces.search(filters,
                        function(response) {
                            ctrl.isLoading = false;
                            $scope.loading = false;
                            $scope.placeCounts = response.placeCounts;
                            $scope.places = response.places;

                            _.forEach($scope.places, function (p) {
                                p.transferReportBaseUrl = $scope.transferReportBaseUrl;
                            })

                            setTotalToolsForFilters();
                            $scope.hasResults = $scope.places.length > 0;
                            $scope.hasFilters = (ctrl.searchTerm !== null && ctrl.searchTerm.length > 0) || $scope.typeIdFilters.length > 0;
                            setNoPlaceDisplay();
                            $scope.hasInventoryItems = response.hasInventoryItems;
                            $scope.totalPages = getTotalPages();
                            $scope.selectedPlace = $scope.getSelectedPlace($scope.selectedPlaceId);
                            if ($scope.selectedPlace) {
                                $scope.selectedPlace.isCurrentSelection = true;
                            }
                            if (!$scope.hasResults) {
                                $scope.searchContainer = null;
                                $scope.searchCloseButton = null;
                                $scope.placesSearchInput = null;
                            }
                            featureToggle.getAll()
                                .then(function (featuresResponse) {
                                    var geofenceEnabled = featuresResponse.geofence;
                                    _.forEach($scope.places, function (place) {
                                        place.enableGeofence = geofenceEnabled;
                                    });
                                });
                        });
                };

                $scope.getSelectedPlace = function(selectedPlaceId) {
                    var selectedPlace = $scope.places.filter(function(place) {
                        return place.placeId === selectedPlaceId;
                    });
                    return selectedPlace.length > 0 ? selectedPlace[0] : null;
                };

                $scope.getPeople = function() {
                    metPeople.getAll(null,
                        function(response) {
                            $scope.people = response.items;
                        },
                        function(error) {
                            console.log(error);
                        });
                };

                $scope.showDeleteConfirmDialog = function(evt) {
                    var parent = angular.element(document.querySelector('#placeDetailEdit_' + evt.placeId));
                    // if the type is unspecified then we are deleting fromthe migration element
                    if (evt.typeId === 1) {
                        parent = angular.element(document.querySelector('#placeMigration_' + evt.placeId));
                    }
                    $mdDialog.show({
                            templateUrl: metUrls('confirmDeletePlaceHtml'),
                            controller: DialogController,
                            parent: parent,
                            targetEvent: evt,
                            clickOutsideToClose: false,
                            fullscreen: true
                        })
                        .then(function(answer) {
                            if (answer === 'delete') {
                                $scope.deletePlace(evt);
                            }
                        });
                };

                function DialogController(scope, $mdDialog) {
                    scope.placeModel = $scope.place;
                    scope.messages = $scope.messages;

                    scope.hide = function() {
                        $mdDialog.hide();
                    };

                    scope.cancel = function() {
                        $mdDialog.cancel();
                    };

                    scope.answer = function(answer) {
                        $mdDialog.hide(answer);
                    };
                }

                function setTotalToolsForFilters() {
                    if ($scope.allPlaceFilter) {
                        $scope.totalTools = $scope.placeCounts.totalToolCount;
                    }
                    if ($scope.projectJobFilter) {
                        $scope.totalTools = $scope.placeCounts.projectJobToolCount;
                    }
                    if ($scope.homeBaseFilter) {
                        $scope.totalTools = $scope.placeCounts.homeBaseToolCount;
                    }
                    if ($scope.vehicleFilter) {
                        $scope.totalTools = $scope.placeCounts.vehicleToolCount;
                    }
                    if (ctrl.searchTerm) {
                        $scope.totalTools = $scope.placeCounts.searchTermToolCount;
                    }
                }

                function setSortField(sortField, direction) {
                    if (direction) {
                        $scope.sortAscending = direction;
                    }
                    else {
                        $scope.sortAscending = (sortField === $scope.currentSortField) ? !$scope.sortAscending : true;
                    }
                    $scope.currentSortField = sortField;
                    $scope.getPlaces();
                }

                $scope.searchKeyUp = function($event) {
                    if ($event.keyCode === 13) {
                        $scope.getPlaces();
                        $scope.toggleSearchContainer(true);
                    }
                }

                $scope.setPlaceFilter = function(allPlaceFilter,
                    projectJobFilter,
                    vehicleFilter,
                    homeBaseFilter,
                    unspecifiedFilter) {
                    $scope.allPlaceFilter = allPlaceFilter;
                    $scope.projectJobFilter = projectJobFilter;
                    $scope.vehicleFilter = vehicleFilter;
                    $scope.homeBaseFilter = homeBaseFilter;
                    $scope.unspecifiedFilter = unspecifiedFilter;
                    //Always start with an empty array when changing the placeType filter
                    $scope.typeIdFilters = [];
                    if ($scope.allPlaceFilter) {
                        $scope.typeIdFilters = [];
                    }
                    if ($scope.projectJobFilter) {
                        $scope.typeIdFilters.push(2);
                    }
                    if ($scope.homeBaseFilter) {
                        $scope.typeIdFilters.push(3);
                    }
                    if ($scope.vehicleFilter) {
                        $scope.typeIdFilters.push(4);
                    }
                    if ($scope.unspecifiedFilter) {
                        $scope.typeIdFilters.push(1);
                    }
                    $scope.setSortField('name', true);
                    resetPaging();
                };

                function getSkipTotal() {
                    return $scope.resultsPerPage * $scope.pageIndex;
                };

                function clearSearch() {
                    ctrl.searchTerm = "";
                    $scope.getPlaces();
                    toggleSearchContainer(true);
                }

                function toggleSearchContainer(close) {
                    if (!$scope.searchContainer) {
                        $scope.searchContainer = document.getElementById('places-search-container');
                        $scope.searchCloseButton = document.getElementById('places-close-expansion-box-icon');
                        $scope.placesSearchInput = document.getElementById('places-search-input');
                    };
                    var classes = $scope.searchContainer.classList;

                    var collapseBox = function() {
                        classes.remove('expanded');
                        $scope.searchCloseButton.style.display = 'none';
                    };

                    var expandBox = function() {
                        classes.add('expanded');
                        $scope.searchCloseButton.style.display = 'block';
                        $scope.placesSearchInput.focus();
                    };

                    if (close) {
                        collapseBox();
                    }
                    else {
                        expandBox();
                    };
                };

                function initialize(placeId, transferReportBaseUrl) {
                    $scope.transferReportBaseUrl = transferReportBaseUrl
                    ctrl.isLoading = true;
                    if (localStorage.getItem('transferFrom')) {
                        $scope.selectedPlaceId = parseInt(localStorage.getItem('transferFrom'));
                    }
                    if (!localStorage.getItem('transferFrom') && localStorage.getItem('transferTo')) {
                        $scope.selectedPlaceId = parseInt(localStorage.getItem('transferTo'));
                    }
                    var n = localStorage.getItem('placesPageNumber');
                    if (n && n !== $scope.currentPage.toString()) {
                        $scope.goToPage(parseInt(localStorage.getItem('placesPageNumber')));
                    }
                    var seenPlaces = localStorage.getItem("seenPlaces");
                    if (!seenPlaces) {
                        $scope.learnMore = true;
                        localStorage.setItem("seenPlaces", true);
                        $rootScope.$broadcast('seen-places-badge', {});
                    }
                    metPlaces.counts(function (result) {
                        if (result.unspecifiedCount > 0 && !seenPlaces) {
                            $scope.setPlaceFilter(false, false, false, false, true);
                        }
                        $scope.currentSortField = 'name';
                        $scope.sortAscending = true;
                        var places = $scope.getPlaces(placeId);
                        places.$promise.then(function () {
                            ctrl.isLoading = false;
                        });
                    },
                        function (error) {
                            console.log(error);
                        });

                    $scope.getDivisions();
                    $scope.getPeople();
                };

                // First, checks if it isn't implemented yet.
                if (!String.prototype.format) {
                    String.prototype.format = function() {
                        var args = arguments;
                        return this.replace(/{(\d+)}/g,
                            function(match, number) {
                                return typeof args[number] != 'undefined'
                                    ? args[number]
                                    : match;
                            });
                    };
                }
            }
        ]);
}());

(function() {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metInventoryOverTimeByPlace',
        [
            'urls', 'localize', 'dates', '$modal', 'modalOptionsService', 'historyService',
            function(metUrls, metLocalize, metDates, $modal, modalOptionsService, metHistoryService) {
                return {
                    restrict: 'E',
                    replace: true,
                    templateUrl: metUrls('inventoryOverTimeByPlaceHtml'),
                    scope: {
                        place: '='
                    },
                    link: function(scope) {
                        scope.refreshIotGraph = refreshIotGraph;
                        scope.metHistoryService = metHistoryService;
                        scope.seriesName = '';
                        scope.currentSeriesData = [];
                        scope.iotPlaceOptions = {};
                        scope.iotPlaceGraph;
                        scope.messages = {
                            from: metLocalize('commands', 'from'),
                            to: metLocalize('commands', 'to'),
                            inventoryChangesOverTime: metLocalize('titles', 'inventoryChangesOverTime'),
                            itemsInInventory: metLocalize('messages', 'itemsInInventory'),
                            itemsAddedToInventory: metLocalize('messages', 'itemsAddedSuccessfully'),
                            itemsRemovedFromInventory: metLocalize('messages', 'itemsRemovedFromInventory')
                        };

                        scope.iotPlaceOptions = {
                            chart: {
                                renderTo: '',
                                zoomType: 'x',
                                height: 330,
                                spacingTop: 80
                            },
                            credits: {
                                enabled: false
                            },
                            legend: {
                                enabled: false
                            },
                            title: {
                                text: '',
                                y: -50
                            },
                            xAxis: {
                                type: 'datetime'
                            },
                            yAxis: {
                                id: 'inventoryCount',
                                allowDecimals: false,
                                title: {
                                    text: ''
                                }
                            },
                            tooltip: {
                                xDateFormat: '%W',
                                pointFormatter: function () {
                                    return '<b>' + this.y + '</b> ' + scope.messages.itemsInInventory.value;
                                }
                            },
                            plotOptions: {
                                pointWidth: 16,
                                negativeColor: '#575757',
                                pointPadding: 0
                            },
                            series: [
                                {
                                    id: 'iotData',
                                    name: '',
                                    type: 'column',
                                    data: scope.currentSeriesData
                                }
                            ],
                            loading: false
                        };

                        scope.$watch('place.isExpanded',
                            function(newValue) {
                                if (newValue) {
                                    scope.refreshIotGraph(scope.place.placeId);
                                }
                            });

                        // -- the Highcharts namespace is exported from the Highcharts library - no other declaration is needed
                        Highcharts.dateFormats = {
                            W: function(timestamp) {
                                var formatString = metDates.date(true);
                                var yre = /([y]+)/gi;
                                var mre = /([m]+)/gi;
                                var dre = /([d]+)/gi;
                                var sre = /(\/)+/gi;
                                var hcf = formatString.replace(yre, '%Y').replace(mre, '%B').replace(dre, '%e').replace(sre, ' ');
                                return Highcharts.dateFormat(hcf, timestamp);
                            }
                        }

                        function getSeriesData(data) {
                            return data.history.map(function(obj) {
                                return [moment(obj.date).valueOf(), obj.count];
                            });
                        }

                        function refreshIotGraph(placeId) {
                            scope.metHistoryService.getHistoricalDataByPlace(placeId)
                                .then(
                                    function(data) {
                                        if (data.status === 200) {
                                            setChartOptions(placeId);
                                            scope.currentSeriesData = getSeriesData(data);
                                            setChartStartEndDates();
                                            scope.yAxisLabel = data.name;
                                            scope.chartDateRange = {
                                                'start': scope.chartStartDate,
                                                'end': scope.chartEndDate
                                            };
                                            scope.chartDateRange['default-start'] = scope.chartDateRange.start;
                                            scope.chartDateRange['default-end'] = scope.chartDateRange.end;
                                            metLocalize('fieldNames', 'itemCount').promise.then(function(val) {
                                                scope.seriesName = val;
                                                setYAxisTitle(data.name);
                                                updateChartSeries(scope.currentSeriesData);
                                            });
                                            if (!scope.iotPlaceGraph) {
                                                scope.iotPlaceGraph = new Highcharts.Chart(scope.iotPlaceOptions);
                                            }
                                        }
                                        else {
                                            openModal();
                                        }
                                    },
                                    function() {
                                        openModal();
                                    }
                                );
                        }

                        function setChartOptions(placeId) {
                            scope.iotPlaceOptions.chart.renderTo = 'inventoryOverTimeByPlaceChartContainer_' + placeId;
                            scope.iotPlaceOptions.title.text = scope.messages.inventoryChangesOverTime.value;
                        }

                        function setChartStartEndDates() {
                            if (scope.currentSeriesData.length > 0) {
                                scope.chartStartDate = makeFormattedMoment(scope.currentSeriesData[0][0]);
                                scope.chartEndDate =
                                    makeFormattedMoment(scope.currentSeriesData[scope.currentSeriesData.length - 1][0]);
                            }
                            else {
                                scope.chartStartDate = makeFormattedMoment('2015-01-01T00:00:00');
                                scope.chartEndDate = makeFormattedMoment(moment());
                            }
                        }

                        function makeMoment(dateItem) {
                            return dateItem ? moment(dateItem, metDates.date(false)) : null;
                        }

                        function makeFormattedMoment(dateItem) {
                            var dateTime = moment(dateItem);
                            var offset = dateTime.utcOffset();
                            var newDateTime = dateTime.add(offset, 'm');
                            return dateItem ? newDateTime.format('L') : null;
                        }

                        function checkIsDate(dateString) {
                            if (dateString) {
                                return moment(dateString, metDates.date(false)).isValid();
                            }
                            return false;
                        }

                        function checkDateInRange(currentSeriesArray, dateString) {
                            var formattedFirstDate = makeFormattedMoment(currentSeriesArray[0][0]);
                            var formattedLastDate =
                                makeFormattedMoment(currentSeriesArray[currentSeriesArray.length - 1][0]);

                            var firstDate = makeMoment(formattedFirstDate).subtract(1, 'd');
                            var lastDate = makeMoment(formattedLastDate).add(1, 'd');
                            var dateInQuestion = makeMoment(dateString);
                            return dateInQuestion.isBetween(firstDate, lastDate);
                        }

                        function checkDateOrder(firstDate, secondDate) {
                            return makeMoment(firstDate) < makeMoment(secondDate);
                        }

                        function updateChartSeries(seriesArray) {
                            var seriesDef = {
                                id: 'iotData',
                                name: scope.seriesName,
                                type: 'column',
                                data: seriesArray
                            }
                            var seriesData = scope.iotPlaceGraph.get('iotData');
                            seriesData.update(seriesDef, true);
                        }

                        function setYAxisTitle(titleText) {
                            var yAxis = scope.iotPlaceGraph.get('inventoryCount');
                            yAxis.setTitle(({ text: titleText }));
                        }

                        function datesAreDates(firstDate, secondDate) {
                            return checkIsDate(firstDate) && checkIsDate(secondDate);
                        }

                        function datesAreInRange(currentSeriesArray, firstDate, secondDate) {
                            return checkDateInRange(currentSeriesArray, firstDate) &&
                                checkDateInRange(currentSeriesArray, secondDate);
                        }

                        function checkDateEntry(firstDate, secondDate, currentSeriesArray) {
                            return datesAreDates(firstDate, secondDate) &&
                                datesAreInRange(currentSeriesArray, firstDate, secondDate) &&
                                checkDateOrder(firstDate, secondDate);
                        }

                        function resetToInitialState() {
                            scope.chartDateRange.start = scope.chartDateRange['default-start'];
                            scope.chartDateRange.end = scope.chartDateRange['default-end'];
                            updateChartSeries(scope.currentSeriesData);
                        }

                        scope.dateChange = function() {
                            var start = makeMoment(scope.chartDateRange.start).valueOf();
                            var end = makeMoment(scope.chartDateRange.end).valueOf();

                            if (checkDateEntry(scope.chartDateRange.start,
                                scope.chartDateRange.end,
                                scope.currentSeriesData)) {
                                var result = scope.currentSeriesData.filter(
                                    function(item) {
                                        return item[0] > start && item[0] < end;
                                    }
                                );
                                updateChartSeries(result);
                            }
                            else {
                                resetToInitialState();
                            }
                        };

                        function openModal() {
                            $modal.open(modalOptionsService.generalErrorModalOptions);
                        }
                    }
                };
            }
        ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metPlace',
        [
            '$window', 'urls', 'localize', 'dates', '$http', '$mdDialog', 'people', 'locations', '$modal',
            'modalOptionsService', '$rootScope', 'stats',
            function ($window,
                metUrls,
                metLocalize,
                metDates,
                $http,
                $mdDialog,
                metPlacePeople,
                metPlaces,
                $modal,
                modalOptionsService,
                $rootScope,
                metStats
            ) {
                return {
                    restrict: 'E',
                    replace: true,
                    templateUrl: metUrls('placeHtml'),
                    scope: {
                        place: '=metPlace',
                        divisions: '=metDivisions',
                        people: '=metPeople',
                        getPeople: '&metGetPeople',
                        collapseAll: '&metCollapseAll',
                        deleteImage: '&metDeleteImage',
                        deletePlace: '&metDeletePlace',
                        updatePlaceCounts: '&metUpdatePlaceCounts',
                        showDeleteConfirmDialog: '&metShowDeleteConfirmDialog',
                        hasInventoryItems: '=metHasInventoryItems'
                    },
                    link: function (scope) {
                        scope.dateTimeFormat = metDates.shortDateTime(true);
                        scope.dateFormat = metDates.date(true);
                        scope.formattedStartDate = makeFormattedMoment(scope.place.startDate);
                        scope.formattedEndDate = makeFormattedMoment(scope.place.endDate);
                        scope.initialStartDateDisplay = '';
                        scope.initialEndDateDisplay = '';
                        scope.startDatePickerOptions = metDates.getDatePickerOptions();
                        scope.endDatePickerOptions = metDates.getDatePickerOptions();
                        scope.isEdit = false;
                        scope.setType = false;
                        scope.openPeopleEdit = openPeopleEdit;
                        scope.isPeopleEdit = false;
                        scope.isLocationEdit = false;
                        scope.isDeleteMenu = false;
                        scope.setEdit = setEdit;
                        scope.toggleEditLocation = toggleEditLocation;
                        scope.sendToInventory = sendToInventory;
                        scope.sendToTransfers = sendToTransfers;
                        scope.sendToReports = sendToReports;
                        scope.exportUserInventoryForPlace = exportUserInventoryForPlace;
                        scope.selectedDivision = {};
                        scope.newPersonName = "";
                        scope.placeCopy = {};
                        scope.selectObj = {};
                        scope.placeholder_text = '[Placeholder text]';
                        scope.uploads = [];
                        scope.place.files = [];
                        scope.place.file = {};
                        scope.setPeopleEdit = setPeopleEdit;
                        scope.setEditPerson = setEditPerson;
                        scope.handleNewPersonFormSubmit = handleNewPersonFormSubmit;
                        scope.searchPersonString = '';
                        scope.workingPersonName = '';
                        scope.duplicatePersonName = '';
                        scope.findNameDuplicate = findNameDuplicate;
                        scope.setPlaceType = setPlaceType;
                        scope.isNewPersonInputEmpty = false;
                        scope.migrationSelectedPlaceType = 0;
                        scope.update = update;
                        scope.place.enableSave = false;
                        scope.startingLatitude = angular.copy(scope.place.latitude);
                        scope.startingLongitude = angular.copy(scope.place.longitude);
                        scope.startingGeofence = angular.copy(scope.place.geofence);
                        scope.place.startingAddressLine = angular.copy(scope.place.addressLine);
                        scope.place.startingCityStateZip = angular.copy(scope.place.cityStateZip);
                        scope.cancelLocation = cancelLocation;
                        scope.groupedPeople = {};
                        scope.selectedPeople = [];
                        scope.peopleSelectionList = [];
                        scope.mostRecentTransfers = [];

                        scope.messages = {
                            add: metLocalize('commands', 'add'),
                            addPersonConversational: metLocalize('commands', 'addPersonConversational'),
                            addressLine: metLocalize('fieldNames', 'addressLine'),
                            alreadyExists: metLocalize('commands', 'alreadyExists'),
                            assign: metLocalize('commands', 'assign'),
                            assignedPeople: metLocalize('messages', 'assignedPeople'),
                            assignExistingPerson: metLocalize('messages', 'assignExistingPerson'),
                            beta: metLocalize('messages','beta'),
                            cancel: metLocalize('commands', 'cancel'),
                            cityStateZip: metLocalize('fieldNames', 'cityStateZip'),
                            continue: metLocalize('fieldNames', 'continue'),
                            costCode: metLocalize('fieldNames', 'costCode'),
                            createReport: metLocalize('commands', 'createReport'),
                            date: metLocalize('fieldNames', 'date'),
                            delete: metLocalize('commands', 'delete'),
                            division: metLocalize('fieldNames', 'division'),
                            downloadInventory: metLocalize('messages', 'downloadInventory'),
                            downloadReport: metLocalize('messages', 'downloadReport'),
                            edit: metLocalize('fieldNames', 'edit'),
                            editLocation: metLocalize('commands', 'editLocation'),
                            editName: metLocalize('messages', 'editName'),
                            editPeopleForThisPlace: metLocalize('titles', 'editPeopleForThisPlace'),
                            endDateConversational: metLocalize('fieldNames', 'endDateConversational'),
                            homeBase: metLocalize('fieldNames', 'homeBase'),
                            items: metLocalize('messages', 'items'),
                            jobNumberConversational: metLocalize('fieldNames', 'jobNumberConversational'),
                            licensePlateConversational: metLocalize('fieldNames', 'licensePlateConversational'),
                            make: metLocalize('fieldNames', 'make'),
                            manageItems: metLocalize('commands', 'manageItems'),
                            manuallyEnterAddress: metLocalize('commands', 'manuallyEnterAddress'),
                            markedMissing: metLocalize('messages', 'markedMissing'),
                            model: metLocalize('fieldNames', 'model'),
                            name: metLocalize('fieldNames', 'name'),
                            needsService: metLocalize('messages', 'needsService'),
                            noResultsFound: metLocalize('messages', 'noResultsFound'),
                            notSeen: metLocalize('messages', 'notSeenFor5Days'),
                            oneKeyItem: metLocalize('messages', 'oneKeyItem'),
                            peopleSelected: metLocalize('messages', 'peopleSelected'),
                            personWillBeAdded: metLocalize('messages', 'personWillBeAdded'),
                            phoneNumberConversational: metLocalize('fieldNames', 'phoneNumberConversational'),
                            projectJob: metLocalize('fieldNames', 'projectJob'),
                            range: metLocalize('fieldNames', 'range'),
                            replace: metLocalize('commands', 'replace'),
                            required: metLocalize('fieldNames', 'required'),
                            save: metLocalize('commands', 'save'),
                            searchAddressPlaceHolder: metLocalize('messages', 'searchAddressPlaceHolder'),
                            searchOrAdd: metLocalize('commands', 'searchOrAdd'),
                            searchForAPerson: metLocalize('commands', 'searchForAPerson'),
                            selectNamesToAdd: metLocalize('messages', 'selectNamesToAdd'),
                            startDateConversational: metLocalize('fieldNames', 'startDateConversational'),
                            totalAssignedPeople: metLocalize('messages', 'totalAssignedPeople'),
                            transferItems: metLocalize('commands', 'transferItems'),
                            useMap: metLocalize('commands', 'useMap'),
                            vehicle: metLocalize('fieldNames', 'vehicle'),
                            vehicleNumber: metLocalize('fieldNames', 'vehicleNumber'),
                            view: metLocalize('commands', 'view'),
                            year: metLocalize('fieldNames', 'year'),
                            startATransfer: metLocalize('messages', 'startATransfer'),
                            gotWhatYouNeed: metLocalize('messages', 'gotWhatYouNeed'),
                            getItemsAssigned: metLocalize('messages', 'getItemsAssigned'),
                            almostThere: metLocalize('messages', 'almostThere'),
                            placeButNoInvenotryItemsText: metLocalize('messages', 'placeButNoInvenotryItemsText'),
                            addItem: metLocalize('commands', 'addItem'),
                            unconverted: metLocalize('messages', 'unconverted'),
                            aboutProjectJob: metLocalize('messages', 'aboutProjectJob'),
                            aboutHomeBase: metLocalize('messages', 'aboutHomeBase'),
                            aboutHomeBase_corrected: metLocalize('messages', 'aboutHomeBase_corrected'),
                            aboutVehicle: metLocalize('messages', 'aboutVehicle'),
                            submit: metLocalize('commands', 'submit'),
                            convertItem: metLocalize('messages', 'convertItem'),
                            dontNeedThisLocation: metLocalize('messages', 'dontNeedThisLocation'),
                            placeType_Unspecified: metLocalize('fieldNames', 'unassigned'),
                            icon: metLocalize('fieldNames', 'icon'),
                            beforeWeCanGetYouDetails: metLocalize('messages', 'beforeWeCanGetYouDetails'),
                            deleteWithItems: metLocalize('messages', 'deleteWithItems'),
                            deleteWithoutItems: metLocalize('messages', 'deleteWithoutItems'),
                            removeLocation: metLocalize('messages', 'removeLocation'),
                            removeLocationConfirm: metLocalize('messages', 'removeLocationConfirm'),
                            remove: metLocalize('commands', 'remove'),
                            addLocationToolTip: metLocalize('messages', 'addLocationToolTip'),
                            clickHereToAddALocation: metLocalize('messages', 'clickHereToAddALocation'),
                            seenOutsideGeofence: metLocalize('messages', 'seenOutsideGeofence'),
                            addGeofence: metLocalize('commands', 'addGeofence'),
                            viewTransferHistoryConversational: metLocalize('commands', 'viewTransferHistoryConversational'),
                            mostRecentTransfers: metLocalize('fieldNames', 'mostRecentTransfers'),
                            emptyTransfersText: metLocalize('messages', 'emptyTransfersText'),
                            noTransfersFound: metLocalize('messages', 'noTransfersFound'),
                            noTransfersForFilter: metLocalize('messages', 'noTransfersForFilter'),
                            itemsOn: metLocalize('fieldNames', 'itemsOn'),
                            unspecified: metLocalize('titles', 'unassigned'),
                            getASnapshot: metLocalize('commands', 'getASnapshot'),
                            createATransfer: metLocalize('commands', 'createATransfer'),
                            generatePdf: metLocalize('commands', 'generatePdf'),
                            noTransferHistory: metLocalize('messages', 'noTransferHistory')
                        }

                        scope.expandPlace = function () {
                            var isExpanded = !scope.place.isExpanded;
                            if (scope.place.typeId === 1) {
                                setType(true);
                            }
                            scope.setEdit(false, false);
                            scope.isPeopleEdit = false;
                            scope.peopleSelectionList = [];
                            scope.newPersonName = '';
                            scope.searchPersonString = '';
                            angular.copy(scope.place, scope.placeCopy);
                            scope.collapseAll();
                            if (scope.place.division) {
                                scope.setSelectedDivision(scope.place.division.divisionName);
                            }
                            if (scope.place.typeId === 2) {
                                setInitialDateDisplay();
                            }
                            scope.closeDeleteMenu();
                            scope.place.isExpanded = isExpanded;
                        }

                        scope.expandCurrentSelection = function () {
                            //-- need to wait for the detail div to be written into the DOM - aarrgghh!
                            if (scope.place.isCurrentSelection) {
                                setTimeout(function () {
                                    var elementId = 'place-detail_' + scope.place.placeId;
                                    var el = document.getElementById(elementId);
                                    if (el) {
                                        scope.expandPlace();
                                        // need to clear out the localStorage item so that on subsequent page visits it doesn't expand
                                        localStorage.removeItem('transferFrom');
                                    }
                                }, 500);
                            }
                        }

                        scope.onDivisionSelect = function ($item) {
                            scope.selectedDivision = $item;
                            scope.place.division = $item;
                            scope.place.divisionId = $item.divisionId;
                        }

                        scope.$watch('isPeopleEdit', function (newValue) {
                            
                            if (newValue === true) {
                                scope.setPeopleEdit(true, false);
                            }
                        });

                        scope.$watch('place.formattedStartDate',
                            function (startDate) {
                                if (startDate) {
                                    var convertedStartDate = moment.utc(startDate, 'MM-DD-YYYY');
                                    var dateInputId = '#endDateInput_' + scope.place.placeId;
                                    if ($(dateInputId).data("DateTimePicker")) {
                                        $(dateInputId).data("DateTimePicker").minDate(moment(convertedStartDate));
                                    }
                                }
                            });

                        scope.$watch('place.formattedEndDate',
                            function (endDate) {
                                if (endDate) {
                                    var convertedEndDate = moment.utc(endDate, 'MM-DD-YYYY');
                                    var dateInputId = '#startDateInput_' + scope.place.placeId;
                                    if ($(dateInputId).data("DateTimePicker")) {
                                        $(dateInputId).data("DateTimePicker").maxDate(moment(convertedEndDate));
                                    }
                                }
                            });

                        scope.$watch('place.formattedStartDate',
                            function (newValue) {
                                if (newValue) {
                                    scope.place.startDate = makeLocalMoment(metDates.convertLocalToUtc(newValue));
                                }
                            });

                        scope.$watch('place.formattedEndDate',
                            function (newValue) {
                                if (newValue) {
                                    scope.place.endDate = makeLocalMoment(metDates.convertLocalToUtc(newValue));
                                }
                            });

                        scope.$watch('place.imageUrl',
                            function (newValue) {
                                scope.place.imageUrl = newValue;
                            });

                        scope.$watch('place.placeName',
                            function (newValue) {
                                scope.place.placeName = newValue;
                            });

                        scope.$watch('place.jobNumber',
                            function (newValue) {
                                scope.place.jobNumber = newValue;
                            });

                        scope.$watch('place.phoneNumber',
                            function (newValue) {
                                scope.place.phoneNumber = newValue;
                            });

                        scope.$watch('place.vehicleModel',
                            function (newValue) {
                                scope.place.vehicleModel = newValue;
                            });

                        scope.$watch('place.vehicleYear',
                            function (newValue) {
                                scope.place.vehicleYear = newValue;
                            });

                        scope.$watch('place.licensePlate',
                            function (newValue) {
                                scope.place.licensePlate = newValue;
                            });

                        scope.$watch('searchPersonString',
                            function (newValue, oldValue) {
                                if (newValue === '' && oldValue.length) {
                                    scope.setPeopleEdit(true, false);
                                }
                            });

                        scope.firstLetterDivisionGroupFn = function (item) {
                            return item.divisionName.charAt(0).toUpperCase();
                        };

                        scope.orderFilterFn = function (groups) {
                            return groups;
                        };

                        scope.setSelectedDivision = function (name) {
                            scope.selectedDivision = scope.divisions.filter(function (division) {
                                return division.divisionName === name;
                            })[0];
                        }

                        scope.selectChange = function (obj) {
                            scope.selectObj = obj;
                        };

                        scope.toggleDeleteMenu = function () {
                            scope.isDeleteMenu = !scope.isDeleteMenu;
                        };

                        scope.closeDeleteMenu = function () {
                            scope.isDeleteMenu = false;
                        };

                        scope.searchKeyUp = function (evt) {
                            if (evt.target.value !== '') {
                                var re = new RegExp(evt.target.value, 'gi');
                                var tempArray = scope.people.filter(function (person) { return re.test(person.personName) });
                                scope.peopleSelectionList = tempArray.sort(function (a, b) { return a.index - b.index });
                            }
                        }

                        scope.newPersonKeyUp = function (evt) {
                            var re = new RegExp('\\S', 'g');
                            scope.isNewPersonInputEmpty = re.test(evt.target.value) ? false : true;
                        }

                        scope.handleCheckboxCheck = function(person) {
                            person.selected = !person.selected;
                            scope.updatePerson(person);
                            scope.searchPersonString = '';
                        };

                        scope.updatePerson = function(person) {
                            metPlacePeople.update(person,
                                function(response) {
                                    person.selected = response.selected;
                                    scope.setPeopleEdit(true, false);
                                    updatePeopleCount();
                                    scope.newPersonName = '';
                                },
                                function(error) {
                                    console.log(error);
                                });
                        };

                        scope.addNewPerson = function(newPersonName) {
                            metPlacePeople.create(
                                {
                                    isDeleted: false,
                                    itemCount: 0,
                                    personId: null,
                                    personName: newPersonName
                                },
                                function(response) {
                                    var person = {
                                        isDeleted: response.isDeleted,
                                        itemCount: response.itemCount,
                                        personId: response.personId,
                                        personName: response.personName
                                    };
                                    scope.people.push(person);
                                    scope.handleCheckboxCheck(person);
                                },
                                function(error) {
                                    console.log(error);
                                });
                        };

                        function setPlaceType() {
                            scope.place.typeId = scope.migrationSelectedPlaceType;
                            setType(false);
                            metPlaces.update(scope.place,
                                function (response) {
                                    scope.place = response;
                                    setDetailType();
                                    response.isEdit = true;
                                    response.isExpanded = true;
                                    scope.updatePlaceCounts();
                                },
                                function (error) {
                                    if (error.data.message) {
                                        console.log(error.data.message);
                                    }
                                });
                        }

                        function handleNewPersonFormSubmit() {
                            var existingPersons = findNameDuplicate(scope.newPersonName);
                            if (existingPersons.length) {
                                scope.person = existingPersons[0];
                                createPlacesCheckDuplicateNameModal(scope.person);
                            }
                            else {
                                scope.isNewPersonInputEmpty = !scope.newPersonName.length;
                                if (!scope.isNewPersonInputEmpty) {
                                    createPlacesAddPersonModal();
                                }
                            }
                        }

                        function findNameDuplicate(personName) {
                            var nameMatch = function (person) {
                                var re = new RegExp('^' + personName + '$', 'i');
                                return re.test(person.personName);
                            }
                            return scope.people.filter(nameMatch);
                        }

                        function setEditPerson(person) {
                            scope.person = person;
                            createPlacesEditNameModal(person);
                        }

                        function createPlacesCheckDuplicateNameModal(person) {
                            var modalOptions = modalOptionsService.placesCheckDuplicateNameModalOptions;
                            modalOptions.controller = function ($scope, $modalInstance) {
                                $scope.newPersonName = scope.newPersonName;
                                $scope.place = scope.place;
                                $scope.assign = assign;
                                $scope.cancel = cancel;
                                $scope.placesCheckDuplicateNameInit = placesCheckDuplicateNameInit;

                                function assign() {
                                    if (person.selected === false) {
                                        scope.handleCheckboxCheck(person);
                                    }
                                    else {
                                        scope.newPersonName = '';
                                    }
                                    $modalInstance.close();
                                }

                                function cancel(reason) {
                                    scope.newPersonName = '';
                                    $modalInstance.dismiss(reason);
                                }

                                function placesCheckDuplicateNameInit() {
                                    $scope.messages = modalOptionsService.placesCheckDuplicateNameModalOptions.messages;
                                }
                            };
                            $modal.open(modalOptions);
                        }

                        function createPlacesAddPersonModal() {
                            var modalOptions = modalOptionsService.placesAddPersonModalOptions;
                            modalOptions.controller = function ($scope, $modalInstance) {
                                $scope.newPersonName = scope.newPersonName;
                                $scope.place = scope.place;
                                $scope.saveAndContinue = saveAndContinue;
                                $scope.cancel = cancel;
                                $scope.placesAddPersonInit = placesAddPersonInit;

                                function saveAndContinue() {
                                    scope.addNewPerson($scope.newPersonName);
                                    $modalInstance.close();
                                }

                                function cancel(reason) {
                                    scope.newPersonName = '';
                                    $modalInstance.dismiss(reason);
                                }

                                function placesAddPersonInit() {
                                    $scope.messages = modalOptionsService.placesAddPersonModalOptions.messages;
                                }
                            };
                            $modal.open(modalOptions);
                        }

                        function createPlacesEditNameModal(person) {
                            scope.workingPersonName = person.personName;
                            var modalOptions = modalOptionsService.placesEditNameModalOptions;
                            modalOptions.controller = function ($scope, $modalInstance) {
                                $scope.newPersonName = scope.newPersonName;
                                $scope.workingPersonName = scope.workingPersonName;
                                $scope.personModel = person;
                                $scope.place = scope.place;
                                $scope.findNameDuplicate = scope.findNameDuplicate;
                                $scope.duplicatePersonNameo = '';
                                $scope.duplicate = false;
                                $scope.save = save;
                                $scope.cancel = cancel;
                                $scope.placesEditNameInit = placesEditNameInit;

                                $scope.$watch('personModel.personName',
                                    function (newValue) {
                                        var existingPeople = findNameDuplicate(newValue);
                                        if ($scope.personModel) {
                                            var inputContainerId = '#container_' +
                                                $scope.place.placeId +
                                                '_' +
                                                $scope.personModel.personId;
                                            var inputContainer = $(inputContainerId);
                                            if (existingPeople.length > 1) {
                                                $scope.duplicatePersonNameo = existingPeople[1].personName;
                                                $scope.duplicate = true;
                                                $(inputContainer).removeClass('md-input-has-value')
                                                    .addClass('md-input-invalid');
                                            }
                                            else {
                                                $scope.duplicate = false;
                                                $(inputContainer).removeClass('md-input-invalid')
                                                    .addClass('md-input-has-value');
                                            }
                                        }
                                    });

                                function save() {
                                    scope.updatePerson($scope.personModel);
                                    $modalInstance.close();
                                }

                                function cancel(reason) {
                                    scope.person.personName = scope.workingPersonName;
                                    scope.workingPersonName = '';
                                    $modalInstance.dismiss(reason);
                                }

                                function placesEditNameInit() {
                                    $scope.messages = modalOptionsService.placesEditNameModalOptions.messages;
                                }
                            };
                            $modal.open(modalOptions);
                        }

                        function toggleEditLocation(fromAddGeofence) {
                            scope.isLocationEdit = !scope.isLocationEdit;
                            if (fromAddGeofence === true) {
                                scope.place.fromAddGeofence = true;
                            } else {
                                scope.place.fromAddGeofence = false;
                            }
                        }

                        function setEdit(isEdit, isCancel) {
                            scope.isEdit = isEdit;
                            scope.closeDeleteMenu();
                            if (isCancel) {
                                scope.place = scope.placeCopy;
                                scope.placeCopy = {};
                                scope.selectedDivision = {};
                                scope.place.isExpanded = true;
                                if (scope.place.divisionId > 0) {
                                    scope.setSelectedDivision(scope.place.division.divisionName);
                                }
                                if (scope.selectObj) {
                                    scope.selectObj.selected = scope.selectedDivision;
                                }
                            }
                            if (isEdit && scope.place.typeId === 2) {
                                setInitialDateDisplay();
                            }
                        }

                        function setType(setType) {
                            scope.setType = setType;
                            scope.closeDeleteMenu();
                        }

                        function sendToInventory(inventoryFilter, place) {
                            var placeFilter = [
                                {
                                    "id": place.placeId,
                                    "label": place.placeName,
                                    "filterName": 'place',
                                    "isSaved": true,
                                    "isSelected": true
                                }
                            ];
                            if (inventoryFilter === 'markedMissing') {
                                var markedMissing =
                                    {
                                        "id": 1,
                                        "label": 'Missing',
                                        "filterName": 'status',
                                        "isSaved": true,
                                        "isSelected": true,
                                        "isQuickFilter": true,
                                        "value": true
                                    };
                                placeFilter.push(markedMissing);
                            }
                            if (inventoryFilter === 'needsService') {
                                var needsService =
                                    {
                                        "id": 1,
                                        "label": 'maintenanceNeeded',
                                        "filterName": 'maintenance',
                                        "isSaved": true,
                                        "isSelected": true,
                                        "isQuickFilter": true,
                                        "value": true
                                    };
                                placeFilter.push(needsService);
                            }

                            if (inventoryFilter === 'unseen') {
                                var unseen =
                                    {
                                        "id": 1,
                                        "label": 'unseen',
                                        "filterName": 'unseen',
                                        "isSaved": true,
                                        "isSelected": true,
                                        "isQuickFilter": true,
                                        "value": 5
                                    };
                                placeFilter.push(unseen);
                            }
                            if (inventoryFilter === 'outsideGeofence') {
                                var outsideGeofence =
                                    {
                                        "id": 1,
                                        "label": 'outsideGeofence',
                                        "filterName": 'outsideGeofence',
                                        "isSaved": true,
                                        "isSelected": true,
                                        "isQuickFilter": true,
                                        "value": true
                                    };
                                placeFilter.push(outsideGeofence);
                            }
                            localStorage.setItem('selectedFilters', JSON.stringify(placeFilter));
                            if (place) {
                                localStorage.setItem('transferFrom', place.placeId);
                            }
                            window.location.pathname = '/inventory';
                        }

                        function sendToTransfers(place) {
                            if (place.itemCount > 0) {
                                localStorage.setItem('transferFrom', place.placeId);
                            }
                            if (place.itemCount === 0) {
                                localStorage.setItem('transferTo', place.placeId);
                            }
                            window.location.pathname = '/Transfers';
                        }

                        function sendToReports(place) {
                            if (place) {
                                localStorage.setItem('transferFrom', place.placeId);
                            }
                            window.location.pathname = '/Reports/Inventory/';
                        }

                        function exportUserInventoryForPlace(place) {
                            var url = metUrls('apiBulkOperations').concat('/export/place?placeId=' + place.placeId);
                            $http.get(url, { responseType: 'arraybuffer' })
                                .then(function (response) {
                                    download(response);
                                });
                        }

                        function download(response) {
                            var disposition = response.headers('Content-Disposition');
                            var fileName = disposition.split("=")[1].replace(/\"/gi, '');
                            var blob = new Blob([response.data],
                                { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
                            var objectUrl = (window.URL || window.webkitURL).createObjectURL(blob);

                            //Adding a check for IE
                            if (window.navigator.msSaveOrOpenBlob) {
                                window.navigator.msSaveOrOpenBlob(blob, fileName);
                            }
                            else {
                                var downloadLink = angular.element('<a/>');
                                downloadLink.attr({
                                    href: objectUrl,
                                    download: fileName
                                })[0].click();
                            }
                        }

                        function setDetailType() {
                            // -- if there's an image - show the image
                            if (scope.place.imageUrl) {
                                return null;
                            }
                            //-- if there's an address but no image then show only the address
                            if (scope.place.startingAddressLine || scope.place.startingCityStateZip) {
                                scope.place.detailAddress = true;
                                return scope.place.detailAddress;
                            }
                            //-- if there's no address and no image then show icons
                            scope.place.detailEmpty = true;
                            return scope.place.detailEmpty;
                        }

                        function makeLocalMoment(dateItem) {
                            return dateItem ? moment(dateItem).format(metDates.api) : null;
                        }

                        function makeFormattedMoment(dateItem) {
                            return dateItem ? moment(dateItem).format(metDates.date(false)) : null;
                        }

                        function setInitialDateDisplay() {
                            if (!scope.place.startDate) {
                                document.querySelector('#startDateInput_'.concat(scope.place.placeId)).value =
                                    scope.messages.startDateConversational.value;
                            }
                            if (!scope.place.endDate) {
                                document.querySelector('#endDateInput_'.concat(scope.place.placeId)).value =
                                    scope.messages.endDateConversational.value;
                            }
                        }

                        function setPlaceDivision(divisions) {
                            scope.place.division = _.find(divisions,
                                function (division) { return division.divisionId === scope.place.divisionId });
                        }

                        function openPeopleEdit(bValue, placeId) {
                            scope.isPeopleEdit = bValue;
                            $rootScope.$broadcast('placePeopleListOpened', placeId);
                        }

                        function setPeopleEdit(isPeopleEdit, isCancel) {
                            scope.groupedPeople = groupAndSortPeople();
                            scope.selectedPeople = scope.groupedPeople.true;
                            scope.peopleSelectionList = setPeopleSelectionList();
                            scope.isPeopleEdit = isPeopleEdit;
                            if (isCancel) {
                                scope.place = scope.placeCopy;
                                scope.place.isExpanded = true;
                                scope.placeCopy = {};
                                scope.newPersonName = '';
                                scope.searchPersonString = '';
                            }
                        }

                        function setPeopleSelectionList() {
                            if (scope.groupedPeople.false) {
                                return scope.groupedPeople.true
                                    ? scope.groupedPeople.true.concat(scope.groupedPeople.false)
                                    : scope.groupedPeople.false;
                            }
                            else {
                                return scope.groupedPeople.true;
                            }
                        }

                       
                        function updatePeopleCount() {
                            if (scope.groupedPeople.true !== undefined) {
                                scope.place.peopleCount = scope.groupedPeople.true.length;
                            } else {
                                scope.place.peopleCount = 0;
                            }

                            scope.place.personIds = [];
                            _.forEach(scope.groupedPeople.true,
                                function (person) {
                                    scope.place.personIds.push(person.personId);
                                });
                        }

                        function groupAndSortPeople() {
                            var groupBy = function (objectArray, property) {
                                return objectArray.reduce(function (acc, obj, idx) {
                                        var key = obj[property];
                                        if (!acc[key]) {
                                            acc[key] = [];
                                        }
                                        obj.index = idx;
                                        acc[key].push(obj);
                                        return acc;
                                    },
                                    {});
                            };
                            return groupBy(scope.people, 'selected');
                        }

                        function update(place) {
                            if (place.enableSave && scope.place.latitude && scope.place.longitude) {
                                scope.updatePlace(place);
                                toggleEditLocation();
                            }
                            else {
                                // Appending dialog to document.body to cover sidenav in docs app
                                var confirm = $mdDialog.confirm()
                                    .title(scope.messages.removeLocation.value)
                                    .content(scope.messages.removeLocationConfirm.value)
                                    .ok(scope.messages.remove.value)
                                    .parent(angular.element(document.querySelector('#masterForm')))
                                    .cancel(scope.messages.cancel.value);

                                $mdDialog.show(confirm).then(function () {
                                    // Cancel was confirmed
                                    scope.updatePlace(place);
                                    toggleEditLocation();
                                });
                            }
                        }

                        scope.updatePlace = function (place) {
                            metPlaces.update(place,
                                function (response) {
                                    //Removed all collapsing becuase we want to stay on the edit screen
                                    place.startingAddressLine = response.addressLine;
                                    place.startingCityStateZip = response.cityStateZip;
                                    place.latitude = response.latitude;
                                    place.longitude = response.longitude;
                                    //-- if there's an address but no image then show only the address
                                    if (response.addressLine || response.cityStateZip) {
                                        place.detailAddress = true;
                                    }
                                    else if (!response.imageUrl) {
                                        //-- if there's no address and no image then show icons
                                        place.detailEmpty = true;
                                    }
                                    place.errorMessage = null;
                                    $rootScope.$broadcast('update-place', response);
                                    setEdit(false, false);
                                },
                                function (error) {
                                    if (error.data.message) {
                                        place.errorMessage = error.data.message;
                                        setEdit(true, false);
                                        console.log(error.data.message);
                                    }
                                });
                        };

                        function cancelLocation() {
                            metPlaces.getLocation(scope.place.placeId, function (data) {
                                scope.place.geofence = data.geofence;
                                scope.place.cityStateZip = data.cityStateZip;
                                scope.place.addressLine = data.addressLine;
                                scope.place.latitude = data.latitude
                                scope.place.longitude = data.longitude;
                            });
                        }

                        function getRecentTransfers() {
                            var filtersForTransfersDashboard = {
                                divisionIds: [],
                                personIds: [],
                                placeIds: [scope.place.placeId]
                            };
                                metStats.getTransfersByFilters(filtersForTransfersDashboard, function (data) {
                                    scope.mostRecentTransfers = data;
                                    for (var i = 0; i < scope.mostRecentTransfers.length; i++) {
                                        scope.mostRecentTransfers[i].transferredOnLocal = metDates.convertUtcToLocal(scope.mostRecentTransfers[i].transferredOn);
                                    }
                                });
                        };


                        scope.generate = function (id) {
                            scope.timeZone = new jstz.determine().name();
                            var url = scope.place.transferReportBaseUrl + '?Id=' + id + '&timeZone=' + scope.timeZone;
                            document.cookie = "Authorization=Bearer " + localStorage.getItem('access_token') + ";path=/";
                            $window.location.href = url;
                        };

                        scope.viewTransferHistory = function () {
                            $window.location.href = '/transfers/history'
                        }

                        var init = function () {
                            scope.place.formattedStartDate = scope.formattedStartDate;
                            scope.place.formattedEndDate = scope.formattedEndDate;
                            setDetailType();
                            setPlaceDivision(scope.divisions);
                            scope.expandCurrentSelection();
                            getRecentTransfers();
                        }

                        init();
                    }
                };
            }
        ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metPlaceLocation', ['localize', '$compile', 'host', '$http', '$rootScope', 'urls', '$mdDialog', '$timeout', function (metLocalize, $compile, host, $http, $rootScope, metUrls, $mdDialog, $timeout) {
        return {
            restrict: 'E',
            replace: true,
            template: '<div></div>',
            scope: {
                placeModel: '=',
                enableSave: '='
            },
            link: function (scope, element) {
                var selectedShape;
                scope.geofenceChanged = false;
                var polygonArray = [];
                scope.pinDropMode = true;
                if (scope.placeModel.geofence === null || scope.placeModel.geofence === undefined) {
                    scope.placeModel.geofence = {};
                }
                var drawingManager = new google.maps.drawing.DrawingManager({
                    drawingMode: google.maps.drawing.OverlayType.POLYGON,
                    drawingControl: false,
                    drawingControlOptions: {
                        position: google.maps.ControlPosition.LEFT_TOP,
                        drawingModes: [google.maps.drawing.OverlayType.POLYGON, google.maps.drawing.OverlayType.RECTANGLE]
                    },
                    polygonOptions: {
                        fillColor: '#BCDCF9',
                        fillOpacity: 0.5,
                        strokeWeight: 2,
                        strokeColor: '#57ACF9',
                        clickable: false,
                        editable: true,
                        zIndex: 1
                    },
                    rectangleOptions: {
                        fillColor: '#BCDCF9',
                        fillOpacity: 0.5,
                        strokeWeight: 2,
                        strokeColor: '#57ACF9',
                        clickable: false,
                        editable: true,
                        zIndex: 1
                    }
                });
                drawingManager.setDrawingMode(null);
                //Default to NA map view
                var center = new google.maps.LatLng(41.850033, -87.6500523);
                var zoom = 3;
                scope.hasExistingLocation = scope.placeModel.latitude && scope.placeModel.longitude;
                scope.startingLatitude = angular.copy(scope.placeModel.latitude);
                scope.startingLongitude = angular.copy(scope.placeModel.longitude);
                scope.idSuffix = "";
                if (scope.placeModel) {
                    scope.idSuffix = scope.placeModel.placeId;
                }

                if (scope.hasExistingLocation) {
                    center = new google.maps.LatLng(scope.placeModel.latitude, scope.placeModel.longitude);
                }

                if (host.isANZ() && !scope.hasExistingLocation) {
                    center = new google.maps.LatLng(-23.831709, 133.766447);
                }
                if (host.isEMEA() && !scope.hasExistingLocation) {
                    center = new google.maps.LatLng(54.5260, 15.2551);
                }

                var map_options = {
                    zoom: zoom,
                    maxZoom: 20,
                    center: center,
                    streetViewControl: false,
                    mapTypeControlOptions: {
                        style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
                        position: google.maps.ControlPosition.RIGHT_TOP,
                    },
                    fullscreenControl: true,
                    fullscreenControlOptions: {
                        position: google.maps.ControlPosition.RIGHT_TOP,
                    },

                };

                var geocoder = new google.maps.Geocoder;
                var map = new google.maps.Map(element[0], map_options);
                var infowindow;
                /// Drawing shape initialize
                function clearSelection() {
                    if (selectedShape) {
                        selectedShape = null;
                    }
                }

                function setSelection(shape) {
                    clearSelection();
                    selectedShape = shape;
                }

                function deleteSelectedShape(redrawing) {
                    var geofenceRemoveButton = document.getElementById('removeGeofenceButton' + scope.idSuffix);
                    var geofenceButton = document.getElementById('createGeofenceButton' + scope.idSuffix);
                    if (redrawing !== true) {
                        geofenceButton.classList.remove('hide-map-field');
                        geofenceButton.classList.add('show-map-field');
                        geofenceRemoveButton.classList.add('hide-map-field');
                        geofenceRemoveButton.classList.remove('show-map-field');
                    }
                    if (selectedShape) {
                        selectedShape.setMap(null);
                        selectedShape = null;
                        scope.placeModel.geofence.points = null;
                        scope.placeModel.enableSave = true;
                        scope.geofenceChanged = true;
                        $rootScope.$apply();
                        if (scope.pinDropMode) {
                            if (!redrawing) {
                                geofenceButton.classList.remove('hide-map-field');
                                geofenceButton.classList.add('show-map-field');
                                geofenceRemoveButton.classList.add('hide-map-field');
                                geofenceRemoveButton.classList.remove('show-map-field');
                            }
                            drawingManager.setOptions({
                                drawingControl: false
                            });
                        } else {
                            drawingManager.setOptions({
                                drawingControl: true
                            });
                        }
                    }
                }

                function storeCoordinate(latVal, lngVal) {
                    scope.coords.push({ lat: latVal, lng: lngVal });
                }

                function polygonEdited(path) {
                    var latLng = new google.maps.LatLng(scope.placeModel.latitude, scope.placeModel.longitude);
                    var existingCoords = angular.copy(scope.coords);
                    scope.coords = [];
                    for (var x = 0; x < path.getLength(); x++) {
                        storeCoordinate(path.getAt(x).lat(), path.getAt(x).lng());
                    }
                    var polygonShape = new google.maps.Polygon({ paths: scope.coords });
                    var inGeofence = checkIfPlaceIsInGeofence(latLng, polygonShape);
                    if (!inGeofence) {
                        scope.coords = existingCoords;
                        showCantMoveGeofenceAlert();
                        deleteSelectedShape(true);
                        drawLoadedGeofence(existingCoords, true);
                    }
                    scope.placeModel.geofence.points = scope.coords;
                    scope.placeModel.enableSave = true;
                    scope.geofenceChanged = true;
                    $rootScope.$apply();
                }

                function drawLoadedGeofence(coords, doNotFitBounds) {
                    var geofenceCoords = coords;
                    scope.coords = geofenceCoords;
                    scope.placeModel.geofence.points = geofenceCoords;
                    var geofence = new google.maps.Polygon({
                        paths: geofenceCoords,
                        fillColor: '#BCDCF9',
                        fillOpacity: 0.5,
                        strokeWeight: 2,
                        strokeColor: '#57ACF9',
                        clickable: false,
                        editable: true,
                        zIndex: 1
                    });
                    drawingManager.setOptions({
                        drawingControl: false
                    });
                    geofence.getPaths().forEach(function (path) {
                        google.maps.event.addListener(path, 'insert_at', function () {
                            polygonEdited(path)
                        });
                        google.maps.event.addListener(path, 'remove_at', function () {
                            polygonEdited(path)
                        });
                        google.maps.event.addListener(path, 'set_at', function () {
                            polygonEdited(path)
                        });
                    });
                    var geofenceCenter = geofence.getBounds().getCenter();
                    if (!doNotFitBounds) {
                        map.setCenter(geofenceCenter);
                        var zoomLevel = getZoomByBounds(map, geofence.getBounds());
                        map.setZoom(zoomLevel);
                    }
                    geofence.setMap(map);
                    setSelection(geofence);
                }
                function getZoomByBounds(map, bounds) {
                    map.setMapTypeId('roadmap');
                    var MAX_ZOOM = 21;
                    var MIN_ZOOM = 0;

                    var ne = map.getProjection().fromLatLngToPoint(bounds.getNorthEast());
                    var sw = map.getProjection().fromLatLngToPoint(bounds.getSouthWest());

                    var worldCoordWidth = Math.abs(ne.x - sw.x);
                    var worldCoordHeight = Math.abs(ne.y - sw.y);

                    //Fit padding in pixels 
                    var FIT_PAD = 5;

                    for (var zoom = MAX_ZOOM; zoom >= MIN_ZOOM; --zoom) {
                        var height = $(map.getDiv()).height();
                        if (height === 0) {
                            height = 328;
                        }
                        if (worldCoordWidth * (1 << zoom) + 1 * FIT_PAD < $(map.getDiv()).width() &&
                            worldCoordHeight * (1 << zoom) + 1 * FIT_PAD < height)
                            return zoom;
                    }
                    return 0;
                }

                drawingManager.setMap(map);

                google.maps.event.addListener(drawingManager, 'polygoncomplete', function (polygon) {
                    scope.coords = [];
                    for (var i = 0; i < polygon.getPath().getLength(); i++) {
                        storeCoordinate(polygon.getPath().getAt(i).lat(), polygon.getPath().getAt(i).lng());
                    }
                    polygonArray.push(polygon);
                    scope.placeModel.geofence.points = scope.coords;

                    polygon.getPaths().forEach(function (path) {
                        google.maps.event.addListener(path, 'insert_at', function () {
                            polygonEdited(path)
                        });
                        google.maps.event.addListener(path, 'remove_at', function () {
                            polygonEdited(path)
                        });
                        google.maps.event.addListener(path, 'set_at', function () {
                            polygonEdited(path)
                        });
                    });

                    var latLng = new google.maps.LatLng(scope.placeModel.latitude, scope.placeModel.longitude);
                    var polygonShape = new google.maps.Polygon({ paths: scope.coords });
                    var inGeofence = checkIfPlaceIsInGeofence(latLng, polygonShape);
                    if (!inGeofence) {
                        scope.coords = [];
                        scope.placeModel.geofence.points = scope.coords;
                        showCantDrawGeofenceAlert();
                        deleteSelectedShape(true);
                    }
                });

                google.maps.event.addListener(drawingManager, 'rectanglecomplete', function (e) {
                    scope.coords = [];
                    google.maps.event.addListener(e, 'bounds_changed', function () {
                        var existingCoords = angular.copy(scope.coords);
                        scope.coords = [];
                        var squareBounds = e.bounds;
                        var NEcord = squareBounds.getNorthEast();
                        var SWcord = squareBounds.getSouthWest();
                        var NWcord = new google.maps.LatLng(NEcord.lat(), SWcord.lng());
                        var SEcord = new google.maps.LatLng(SWcord.lat(), NEcord.lng());
                        storeCoordinate(NEcord.lat(), NEcord.lng());
                        storeCoordinate(NWcord.lat(), NWcord.lng());
                        storeCoordinate(SWcord.lat(), SWcord.lng());
                        storeCoordinate(SEcord.lat(), SEcord.lng());

                        var latLong = new google.maps.LatLng(scope.placeModel.latitude, scope.placeModel.longitude);
                        var shape = new google.maps.Polygon({ paths: scope.coords });
                        var inGeofenceFlag = checkIfPlaceIsInGeofence(latLong, shape);
                        if (!inGeofenceFlag) {
                            scope.coords = existingCoords;
                            showCantMoveGeofenceAlert();
                            deleteSelectedShape(true);
                            drawLoadedGeofence(existingCoords, true);
                        }

                        scope.placeModel.geofence.points = scope.coords;
                        scope.placeModel.enableSave = true;
                        scope.geofenceChanged = true;
                        $rootScope.$apply();
                    });
                    var bounds = e.bounds;
                    var NE = bounds.getNorthEast();
                    var SW = bounds.getSouthWest();
                    var NW = new google.maps.LatLng(NE.lat(), SW.lng());
                    var SE = new google.maps.LatLng(SW.lat(), NE.lng());
                    storeCoordinate(NE.lat(), NE.lng());
                    storeCoordinate(NW.lat(), NW.lng());
                    storeCoordinate(SW.lat(), SW.lng());
                    storeCoordinate(SE.lat(), SE.lng());

                    var latLng = new google.maps.LatLng(scope.placeModel.latitude, scope.placeModel.longitude);
                    var polygonShape = new google.maps.Polygon({ paths: scope.coords });
                    var inGeofence = checkIfPlaceIsInGeofence(latLng, polygonShape);
                    if (!inGeofence) {
                        scope.coords = [];
                        showCantDrawGeofenceAlert();
                        deleteSelectedShape(true);
                    } else {
                        scope.placeModel.geofence.points = scope.coords;
                        scope.placeModel.enableSave = true;
                        scope.geofenceChanged = true;
                        $rootScope.$apply();
                    }
                });

                google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
                    if (e.type !== google.maps.drawing.OverlayType.MARKER) {
                        // Switch back to non-drawing mode after drawing a shape.
                        drawingManager.setDrawingMode(null);
                        // To hide:
                        drawingManager.setOptions({
                            drawingControl: false
                        });

                        // Add an event listener that selects the newly-drawn shape when the user
                        // mouses down on it.
                        var newShape = e.overlay;
                        newShape.type = e.type;
                        google.maps.event.addListener(newShape, 'click', function () {
                            setSelection(newShape);
                        });
                        setSelection(newShape);
                        scope.placeModel.enableSave = true;
                        scope.geofenceChanged = true;
                        $rootScope.$apply();
                    }
                });

                google.maps.Polygon.prototype.getBounds = function () {
                    var bounds = new google.maps.LatLngBounds();
                    var paths = this.getPaths();
                    for (var i = 0; i < paths.getLength(); i++) {
                        var path = paths.getAt(i);
                        for (var ii = 0; ii < path.getLength(); ii++) {
                            bounds.extend(path.getAt(ii));
                        }
                    }
                    return bounds;
                }

                // End of Geofence initalize

                //Check if we have the users location and if so zoom map to their location
                var geoOptions = {
                    maximumAge: 5 * 60 * 1000
                }

                var geoSuccess = function (position) {
                    if (scope.placeModel.geofence.points) {
                        return;
                    }
                    var userLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                    var bounds = new google.maps.LatLngBounds();
                    bounds.extend(userLocation);
                    // Extending 2 offset points SW and NE which basically set the zoom since we can't set zoom after fitBounds().
                    var offset = 0.000002;
                    var centerOfBounds = bounds.getCenter();
                    bounds.extend(new google.maps.LatLng(centerOfBounds.lat() + offset, centerOfBounds.lng() + offset));
                    bounds.extend(new google.maps.LatLng(centerOfBounds.lat() - offset, centerOfBounds.lng() - offset));
                    map.fitBounds(bounds);
                };
                var geoError = function (error) {
                    console.log('Error occurred. Error code: ' + error.code);
                    // error.code can be:
                    //   0: unknown error
                    //   1: permission denied
                    //   2: position unavailable (error response from location provider)
                    //   3: timed out
                };

                navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);


                var placeService = new google.maps.places.PlacesService(map);
                var resultBox = document.createElement('div');
                // Create the search box and link it to the UI element.
                var input = document.createElement('input');
                metLocalize('messages', 'searchAddressPlaceHolder').promise.then(function (val) {
                    input.placeholder = val;
                });
                input.setAttribute("data-ng-model", 'searchText');
                input.classList.add('map-search-box');
                input.classList.add('clearable');
                input.id = 'searchBoxInput' + scope.idSuffix;
                var searchBox = new google.maps.places.SearchBox(input);
                resultBox.appendChild(input);

                // Bias the SearchBox results towards current map's viewport.
                map.addListener('bounds_changed',
                    function () {
                        searchBox.setBounds(map.getBounds());
                    });

                var imageAndAddressBox = document.createElement('div');
                var imageBox = document.createElement('div');
                var image = document.createElement('img');
                var addressBox = document.createElement('div');
                var setLocationLabel = document.createElement('div');
                var addressLineLabel = document.createElement('div');
                var cityStateZipLabel = document.createElement('div');
                var createGeofenceButton = document.createElement('button');
                var removeGeofenceButton = document.createElement('button');
                var geofenceOverlay = document.createElement('div');
                var geofenceOverlayLabel = document.createElement('div');
                var geofenceBack = document.createElement('div');
                var geofenceClear = document.createElement('div');

                metLocalize('commands', 'addGeofence').promise.then(function (val) {
                    geofenceOverlayLabel.innerText = val;
                });
                metLocalize('commands', 'back').promise.then(function (val) {
                    geofenceBack.innerText = val;
                });
                metLocalize('messages', 'clearFence').promise.then(function (val) {
                    geofenceClear.innerText = val;
                });

                geofenceOverlay.appendChild(geofenceBack);
                geofenceOverlay.appendChild(geofenceOverlayLabel);
                geofenceOverlay.appendChild(geofenceClear);

                var buttonBox = document.createElement('div');

                setLocationLabel.classList.add('hide-map-field');
                addressLineLabel.classList.add('hide-map-field');
                cityStateZipLabel.classList.add('hide-map-field');
                createGeofenceButton.classList.add('hide-map-field');
                removeGeofenceButton.classList.add('hide-map-field');
                metLocalize('commands', 'setLocation').promise.then(function (val) {
                    setLocationLabel.innerText = val;
                });

                addressBox.classList.add('map-address-box');
                image.id = 'imageId' + scope.idSuffix;
                imageBox.appendChild(image);
                imageAndAddressBox.appendChild(imageBox);
                imageAndAddressBox.appendChild(addressBox);
                addressBox.appendChild(setLocationLabel);
                addressBox.appendChild(addressLineLabel);
                addressBox.appendChild(cityStateZipLabel);
                buttonBox.classList.add('map-geofence-button');
                buttonBox.appendChild(createGeofenceButton);
                createGeofenceButton.classList.add('met-action-button','primary');
                buttonBox.appendChild(removeGeofenceButton);
                removeGeofenceButton.classList.add('met-action-button', 'primary');
                imageAndAddressBox.appendChild(buttonBox);

                resultBox.classList.add('map-result-box');
                geofenceOverlay.classList.add('geofence-overlay');
                geofenceOverlay.classList.add('hide-map-field');
                geofenceBack.classList.add('geofence-back');
                geofenceClear.classList.add('geofence-clear');
                addressLineLabel.setAttribute("data-ng-model", 'placeModel.addressLine');
                cityStateZipLabel.setAttribute("data-ng-model", 'placeModel.cityStateZip');
                createGeofenceButton.onclick = addGeofence;
                removeGeofenceButton.onclick = deleteSelectedShape;
                geofenceBack.onclick = backFromGeofence;
                geofenceClear.onclick = deleteSelectedShape;
                geofenceOverlay.id = 'geofenceOverlay' + scope.idSuffix;
                addressLineLabel.id = 'mapAddressLineLabel' + scope.idSuffix;
                cityStateZipLabel.id = 'mapCityStateZipLabel' + scope.idSuffix;
                setLocationLabel.id = 'mapSetLocationLabel' + scope.idSuffix;
                createGeofenceButton.id = 'createGeofenceButton' + scope.idSuffix;
                removeGeofenceButton.id = 'removeGeofenceButton' + scope.idSuffix;
                metLocalize('commands', 'addGeofence').promise.then(function (val) {
                    createGeofenceButton.innerText = val;
                });
                metLocalize('commands', 'removeGeofence').promise.then(function (val) {
                    removeGeofenceButton.innerText = val;
                });
                imageAndAddressBox.id = 'imageAndAddressBox' + scope.idSuffix;

                $compile(resultBox)(scope);
                resultBox.appendChild(imageAndAddressBox);

                map.controls[google.maps.ControlPosition.TOP_LEFT].push(resultBox);
                map.controls[google.maps.ControlPosition.TOP_RIGHT].push(geofenceOverlay);

                var markers = [];

                function clearLocation() {
                    var addressLine = document.getElementById('mapAddressLineLabel' + scope.idSuffix);
                    var cityStateZip = document.getElementById('mapCityStateZipLabel' + scope.idSuffix);
                    var imageAndAddress = document.getElementById('imageAndAddressBox' + scope.idSuffix);
                    var setLocation = document.getElementById('mapSetLocationLabel' + scope.idSuffix);
                    var search = document.getElementById('searchBoxInput' + scope.idSuffix);
                    var geofenceButton = document.getElementById('createGeofenceButton' + scope.idSuffix);
                    addressLine.classList.add('hide-map-field');
                    cityStateZip.classList.add('hide-map-field');
                    imageAndAddress.classList.add('hide-map-field');
                    setLocation.classList.add('hide-map-field');
                    geofenceButton.classList.add('hide-map-field');
                    addressLine.classList.remove('show-map-field');
                    cityStateZip.classList.remove('show-map-field');
                    geofenceButton.classList.remove('show-map-field');

                    imageAndAddress.classList.remove('show-map-field');
                    scope.placeModel.latitude = null;
                    scope.placeModel.longitude = null;
                    checkIfLocationChanged();
                    scope.placeModel.addressLine = null;
                    scope.placeModel.cityStateZip = null;
                    search.value = '';
                    markers.forEach(function (marker) {
                        marker.setMap(null);
                    });
                    markers = [];
                }

                function addGeofence() {
                    scope.pinDropMode = false;
                    addressLineLabel.classList.add('hide-map-field');
                    cityStateZipLabel.classList.add('hide-map-field');
                    imageAndAddressBox.classList.add('hide-map-field');
                    setLocationLabel.classList.add('hide-map-field');
                    createGeofenceButton.classList.add('hide-map-field');
                    input.classList.add('hide-map-field');
                    addressLineLabel.classList.remove('show-map-field');
                    cityStateZipLabel.classList.remove('show-map-field');
                    createGeofenceButton.classList.remove('show-map-field');
                    geofenceOverlay.classList.remove('hide-map-field');
                    geofenceOverlay.classList.add('show-map-field');
                    var contentString = '<div>';
                    metLocalize('messages', 'selectDrawingTool').promise.then(function (val) {
                        contentString = contentString + val + '</div>';
                        infowindow = new google.maps.InfoWindow({
                            content: contentString
                        });
                        infowindow.open(map, markers[0]);
                    });
                    google.maps.event.addListener(map, "click", function (event) {
                        infowindow.close();
                    });
                    google.maps.event.addListener(drawingManager, "drawingmode_changed", function () {
                        infowindow.close();
                    })

                    imageAndAddressBox.classList.remove('show-map-field');
                    // To hide:
                    drawingManager.setOptions({
                        drawingControl: true
                    });
                }

                function backFromGeofence() {
                    scope.pinDropMode = true;
                    var addressLine = document.getElementById('mapAddressLineLabel' + scope.idSuffix);
                    var cityStateZip = document.getElementById('mapCityStateZipLabel' + scope.idSuffix);
                    var imageAndAddress = document.getElementById('imageAndAddressBox' + scope.idSuffix);
                    var setLocation = document.getElementById('mapSetLocationLabel' + scope.idSuffix);
                    var search = document.getElementById('searchBoxInput' + scope.idSuffix);
                    var geofenceButton = document.getElementById('createGeofenceButton' + scope.idSuffix);
                    var geofenceRemoveButton = document.getElementById('removeGeofenceButton' + scope.idSuffix);
                    var geofenceOverlayControl = document.getElementById('geofenceOverlay' + scope.idSuffix);
                    addressLine.classList.remove('hide-map-field');
                    cityStateZip.classList.remove('hide-map-field');
                    imageAndAddress.classList.remove('hide-map-field');
                    setLocation.classList.remove('hide-map-field');
                    search.classList.remove('hide-map-field');
                    addressLine.classList.add('show-map-field');
                    cityStateZip.classList.add('show-map-field');
                    if (scope.placeModel.geofence.points) {
                        geofenceRemoveButton.classList.add('show-map-field');
                        geofenceRemoveButton.classList.remove('hide-map-field');
                        geofenceButton.classList.add('hide-map-field');
                        geofenceButton.classList.remove('show-map-field');
                    } else {
                        geofenceButton.classList.remove('hide-map-field');
                        geofenceButton.classList.add('show-map-field');
                        geofenceRemoveButton.classList.remove('show-map-field');
                        geofenceRemoveButton.classList.add('hide-map-field');
                    }
                    geofenceOverlayControl.classList.add('hide-map-field');
                    geofenceOverlayControl.classList.remove('show-map-field');

                    imageAndAddress.classList.add('show-map-field');
                    // To hide:
                    drawingManager.setOptions({
                        drawingControl: false
                    });
                    drawingManager.setDrawingMode(null);
                }

                function checkIfLocationChanged() {
                    if ((scope.startingLatitude !== scope.placeModel.latitude ||
                        scope.startingLongitude !== scope.placeModel.longitude || scope.geofenceChanged)) {
                        scope.placeModel.enableSave = true;
                    } else {
                        scope.placeModel.enableSave = false;
                    }
                    $rootScope.$apply();
                }

                var _interval;
                function geocodeLatLng(geocoderService) {
                    var setCenter = new google.maps.LatLng(markers[0].position.lat(), markers[0].position.lng());
                    geocoderService.geocode({
                        'location': setCenter
                    },
                        function (results, status) {
                            if (status === 'OK' && results[0]) {
                                placeService.getDetails({
                                    placeId: results[0].place_id,
                                    fields: ['name', 'geometry', 'formatted_address', 'address_components', 'photos']
                                },
                                    function (place, resultStatus) {
                                        if (resultStatus === google.maps.places.PlacesServiceStatus.OK) {
                                            processFoundPlace(place);
                                            scope.placeModel.latitude = markers[0].position.lat();
                                            scope.placeModel.longitude = markers[0].position.lng();
                                            checkIfLocationChanged();

                                            if (_interval) {
                                                clearInterval(_interval)
                                            }

                                            _interval = setInterval(function () {
                                                var search = document.getElementById('searchBoxInput' + scope.idSuffix);
                                                if (search) {
                                                    search.value = place.formatted_address;
                                                    $rootScope.$apply();
                                                    $(search)[tog(search.value)]('x');
                                                    clearInterval(_interval);
                                                }
                                                if (scope.$$destroyed) {
                                                    clearInterval(_interval);
                                                }
                                            }, 100);
                                        }
                                    });
                            }
                        });
                };

                function placeMarker(location) {
                    // Clear out the old markers.
                    markers.forEach(function (marker) {
                        marker.setMap(null);
                    });
                    markers = [];
                    markers.push(new google.maps.Marker({
                        position: location,
                        map: map
                    }));
                    geocodeLatLng(geocoder);
                }

                var geoloccontrol = new klokantech.GeolocationControl(map, 17);

                google.maps.event.addListener(map, 'click', function (event) {
                    if (scope.pinDropMode) {
                        var mapHasMarker = false;
                        markers.forEach(function (marker) {
                            if (marker) {
                                mapHasMarker = true;
                            }
                        });
                        if (!mapHasMarker) {
                            placeMarker(event.latLng);
                        } else {
                            if (scope.placeModel.geofence.points) {
                                showOutsideGeofenceAlert();
                            } else {
                                clearLocation();
                            }
                        }
                    }
                });

                function checkIfPlaceIsInGeofence(latLng, shape) {
                    if (shape) {
                        return google.maps.geometry.poly.containsLocation(latLng, shape)
                    }
                    return true;
                }

                // Listen for the event fired when the user selects a prediction and retrieve
                // more details for that place.
                searchBox.addListener('places_changed', function () {
                    var places = searchBox.getPlaces();

                    if (places.length === 0) {
                        return;
                    }

                    // For each place, get the icon, name and location.
                    places.forEach(function (place) {
                        if (scope.placeModel.geofence.points) {
                            showOutsideGeofenceAlert(place);
                        } else {
                            markers.forEach(function (marker) {
                                marker.setMap(null);
                            });
                            markers = [];
                            processFoundPlace(place, true);
                        }
                    });
                });

                function setAddressFileds(address_components) {
                    var addressComponents = {};
                    jQuery.each(address_components, function (k, v1) {
                        jQuery.each(v1.types, function (k2, v2) {
                            addressComponents[v2] = v1.long_name;
                        });
                    });
                    addressLineLabel.innerText = '';
                    cityStateZipLabel.innerText = '';
                    addressLineLabel.innerText =
                        addressComponents.street_number !== undefined ? addressComponents.street_number : '';
                    addressLineLabel.innerText += addressComponents.route !== undefined ? ' ' + addressComponents.route : '';
                    cityStateZipLabel.innerText =
                        addressComponents.locality !== undefined ? addressComponents.locality : '';
                    cityStateZipLabel.innerText += addressComponents.administrative_area_level_1 !== undefined ?
                        ' ' + addressComponents.administrative_area_level_1 :
                        '';
                    cityStateZipLabel.innerText += addressComponents.postal_code !== undefined ?
                        ' ' + addressComponents.postal_code :
                        '';

                    imageAndAddressBox.classList.add('map-image-and-address-box');
                    setLocationLabel.classList.add('map-set-location-label');
                    addressLineLabel.classList.add('map-location-label');
                    cityStateZipLabel.classList.add('map-location-label');
                    setLocationLabel.classList.add('show-map-field');
                    addressLineLabel.classList.add('show-map-field');
                    cityStateZipLabel.classList.add('show-map-field');
                    addressLineLabel.classList.remove('hide-map-field');
                    cityStateZipLabel.classList.remove('hide-map-field');
                    imageAndAddressBox.classList.remove('hide-map-field');
                    setLocationLabel.classList.remove('hide-map-field');
                    if (scope.placeModel.geofence.points) {
                        removeGeofenceButton.classList.add('show-map-field');
                        removeGeofenceButton.classList.remove('hide-map-field');
                    } else {
                        if (scope.placeModel.enableGeofence) {
                            createGeofenceButton.classList.remove('hide-map-field');
                            createGeofenceButton.classList.add('show-map-field');
                        }
                    }

                    scope.placeModel.addressLine = addressLineLabel.innerText;
                    scope.placeModel.cityStateZip = cityStateZipLabel.innerText;
                    if (scope.placeModel.fromAddGeofence === true && scope.placeModel.latitude) {
                        addGeofence();
                    }
                }

                function processFoundPlace(place, placePin) {
                    // To hide:
                    drawingManager.setOptions({
                        drawingControl: false
                    });
                    var bounds = new google.maps.LatLngBounds();
                    if (!place.geometry) {
                        return;
                    }
                    if (placePin) {
                        // Create a marker for each place.
                        markers.push(new google.maps.Marker({
                            map: map,
                            title: place.name,
                            position: place.geometry.location
                        }));
                        scope.placeModel.latitude = markers[0].position.lat();
                        scope.placeModel.longitude = markers[0].position.lng();
                        checkIfLocationChanged();
                    }
                    var imageUrl = '';
                    if (place.photos) {
                        imageUrl = place.photos[0].getUrl({
                            'maxWidth': 325,
                            'maxHeight': 0
                        });
                        imageBox.style.display = 'block';
                    } else {
                        checkIfLocationChanged();
                        imageUrl = '//maps.googleapis.com/maps/api/streetview?size=325x200&location=' +
                            place.formatted_address +
                            '&fov=90&heading=0&pitch=10&key=' + metUrls("googleApiKey");
                    }
                    image.src = imageUrl;
                    imageBox.style.width = '325px';
                    imageBox.style.maxHeight = '180px';
                    imageBox.style.overflow = 'hidden';
                    image.style.maxHeight = 'initial';

                    addressBox.appendChild(cityStateZipLabel);
                    setAddressFileds(place.address_components);
                    if (place.geometry.viewport) {
                        // Only geocodes have viewport.
                        bounds.union(place.geometry.viewport);
                    } else {
                        bounds.extend(place.geometry.location);
                    }

                    if (scope.placeModel.geofence.points) {
                        return;
                    }
                    map.fitBounds(bounds);
                }

                // Bias the SearchBox results towards current map's viewport.
                map.addListener('bounds_changed', function () {
                    searchBox.setBounds(map.getBounds());
                });

                function showOutsideGeofenceAlert(place) {
                    var parent = angular.element(document.querySelector('#place-detail_' + scope.idSuffix));
                    if (/MSIE \d|Trident.*rv:/.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
                        parent = angular.element(document.querySelector('#placesContent'));
                    }
                    $mdDialog.show({
                        templateUrl: metUrls('alertGeofenceRemoval'),
                        controller: DialogController,
                        parent: parent,
                        clickOutsideToClose: false,
                        fullscreen: true
                    })
                        .then(function (answer) {
                            if (answer === 'remove') {
                                clearLocation();
                                deleteSelectedShape();
                                if (place) {
                                    // Clear out the old markers.
                                    markers.forEach(function (marker) {
                                        marker.setMap(null);
                                    });
                                    markers = [];
                                    processFoundPlace(place, true);
                                }
                            }
                            if (answer === 'cancel' && scope.hasExistingLocation) {
                                var pinLocation = new google.maps.LatLng(scope.placeModel.latitude, scope.placeModel.longitude);
                                placeMarker(pinLocation);
                            }
                        });
                };

                function showCantMoveGeofenceAlert() {
                    var parent = angular.element(document.querySelector('#place-detail_' + scope.idSuffix));
                    if (/MSIE \d|Trident.*rv:/.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
                        parent = angular.element(document.querySelector('#placesContent'));
                    }
                    $mdDialog.show({
                        templateUrl: metUrls('alertCantMoveGeofence'),
                        controller: DialogController,
                        parent: parent,
                        clickOutsideToClose: false,
                        fullscreen: true
                    })
                };

                function showCantDrawGeofenceAlert() {
                    var parent = angular.element(document.querySelector('#place-detail_' + scope.idSuffix));
                    if (/MSIE \d|Trident.*rv:/.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
                        parent = angular.element(document.querySelector('#placesContent'));
                    }
                    $mdDialog.show({
                        templateUrl: metUrls('alertCantDrawGeofence'),
                        controller: DialogController,
                        parent: parent,
                        clickOutsideToClose: false,
                        fullscreen: true
                    })
                };

                function DialogController(scope, $mdDialog) {
                    scope.messages = {
                        removeSetLocation: metLocalize('messages', 'removeSetLocation'),
                        removeLocationMessage: metLocalize('messages', 'removeLocationMessage'),
                        cancel: metLocalize('commands', 'cancel'),
                        remove: metLocalize('commands', 'remove'),
                        ok: metLocalize('commands', 'ok'),
                        cantMovePin: metLocalize('messages', 'cantMovePin'),
                        cantMovePinMessage: metLocalize('messages', 'cantMovePinMessage'),
                        cantDrawFence: metLocalize('messages', 'cantDrawFence'),
                        cantDrawFenceMessage: metLocalize('messages', 'cantDrawFenceMessage'),
                    };

                    scope.hide = function () {
                        $mdDialog.hide();
                    };

                    scope.cancel = function () {
                        $mdDialog.cancel();
                    };

                    scope.answer = function (answer) {
                        $mdDialog.hide(answer);
                    };
                }

                window.setTimeout(function () {
                    google.maps.event.trigger(map, 'resize');
                    if (scope.hasExistingLocation) {
                        var pinLocation = new google.maps.LatLng(scope.placeModel.latitude, scope.placeModel.longitude);
                        placeMarker(pinLocation);
                    }
                    if (scope.placeModel.geofence.points) {
                        drawLoadedGeofence(scope.placeModel.geofence.points);
                    }
                }, 500);

                function tog(v) { return v ? 'addClass' : 'removeClass'; }
                $(document).on('input', '.clearable', function () {
                    $(this)[tog(this.value)]('x');
                }).on('mousemove', '.x', function (e) {
                    $(this)[tog(this.offsetWidth - 18 < e.clientX - this.getBoundingClientRect().left)]('onX');
                }).on('change', '.x', function (e) {
                    $(this)[tog(this.offsetWidth - 18 < e.clientX - this.getBoundingClientRect().left)]('onX');
                }).on('touchstart click', '.onX', function (ev) {
                    ev.preventDefault();
                    $(this).removeClass('x onX').val('').change();
                    if (scope.placeModel.geofence.points) {
                        showOutsideGeofenceAlert();
                    } else {
                        clearLocation();
                    }
                });
            }
        }
    }]);
}());
(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metPlaceLocationMini', ['$rootScope', function ($rootScope) {
        return {
            restrict: 'E',
            replace: true,
            template: '<div></div>',
            scope: {
                placeModel: '='
            },
            link: function (scope, element) {
                var center = new google.maps.LatLng(scope.placeModel.latitude, scope.placeModel.longitude);
                var polygon;
                var marker;
                var map_options = {
                    zoom: 15,
                    center: center,
                    streetViewControl: false,
                    disableDefaultUI: true,
                    draggable: false
                };

                var map = new google.maps.Map(element[0], map_options);
                if (scope.placeModel.geofence && scope.placeModel.geofence.points) {
                    var polygonCoords = scope.placeModel.geofence.points;
                    polygon = new google.maps.Polygon({
                        paths: polygonCoords,
                        fillColor: '#BCDCF9',
                        fillOpacity: 0.5,
                        strokeWeight: 2,
                        strokeColor: '#57ACF9',
                        clickable: false,
                        editable: false,
                        zIndex: 1
                    });
                    polygon.setMap(map);
                    google.maps.Polygon.prototype.getBounds = function () {
                        var bounds = new google.maps.LatLngBounds();
                        var paths = this.getPaths();
                        for (var i = 0; i < paths.getLength(); i++) {
                            var path = paths.getAt(i);
                            for (var ii = 0; ii < path.getLength(); ii++) {
                                bounds.extend(path.getAt(ii));
                            }
                        }
                        return bounds;
                    }
                }

                marker = new google.maps.Marker({
                    position: center,
                    map: map
                });

                function zoomMapToPolygon() {
                    google.maps.Polygon.prototype.getBounds = function () {
                        var bounds = new google.maps.LatLngBounds();
                        var paths = this.getPaths();
                        for (var i = 0; i < paths.getLength(); i++) {
                            var path = paths.getAt(i);
                            for (var ii = 0; ii < path.getLength(); ii++) {
                                bounds.extend(path.getAt(ii));
                            }
                        }
                        return bounds;
                    }
                    var zoomLevel = getZoomByBounds(map, polygon.getBounds());
                    map.setZoom(zoomLevel);
                }

                google.maps.event.addListenerOnce(map, 'tilesloaded', function () {
                    // do something only the first time the map is loaded
                    if (scope.placeModel.geofence && scope.placeModel.geofence.points) {
                        zoomMapToPolygon();
                    }
                });
                window.setTimeout(function () {
                    google.maps.event.trigger(map, 'resize');
                }, 500);

                function getZoomByBounds(googleMap, bounds) {
                    googleMap.setMapTypeId('roadmap');
                    var MAX_ZOOM = 21;
                    var MIN_ZOOM = 0;

                    var ne = googleMap.getProjection().fromLatLngToPoint(bounds.getNorthEast());
                    var sw = googleMap.getProjection().fromLatLngToPoint(bounds.getSouthWest());

                    var worldCoordWidth = Math.abs(ne.x - sw.x);
                    var worldCoordHeight = Math.abs(ne.y - sw.y);

                    //Fit padding in pixels 
                    var FIT_PAD = 5;

                    for (var zoom = MAX_ZOOM; zoom >= MIN_ZOOM; --zoom) {
                        if (worldCoordWidth * (1 << zoom) + 1 * FIT_PAD < $(googleMap.getDiv()).width() &&
                            worldCoordHeight * (1 << zoom) + 1 * FIT_PAD < $(googleMap.getDiv()).height()) {
                            return zoom;
                        }
                    }
                    return 0;
                }

                $rootScope.$on('update-place', function () {
                    center = new google.maps.LatLng(scope.placeModel.latitude, scope.placeModel.longitude);
                    marker = new google.maps.Marker({
                        position: center,
                        map: map
                    });
                    if (scope.placeModel.geofence && scope.placeModel.geofence.points !== undefined) {
                        if (polygon) {
                            polygon.setMap(null);
                        }
                        var polygonPoints = scope.placeModel.geofence.points;
                        if (polygonPoints !== null) {
                            polygon = new google.maps.Polygon({
                                paths: polygonPoints,
                                fillColor: '#BCDCF9',
                                fillOpacity: 0.5,
                                strokeWeight: 2,
                                strokeColor: '#57ACF9',
                                clickable: false,
                                editable: false,
                                zIndex: 1
                            });
                            polygon.setMap(map);
                            zoomMapToPolygon();
                        }
                    }
                })
            }
        }
    }]);
}());
(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metPlacePeopleList',
        [
            '$filter', 'urls', 'localize', 'modalOptionsService', '$modal', 'people',
            function ($filter,
                metUrls,
                metLocalize,
                modalOptionsService,
                $modal,
                metPlacePeople) {
                return {
                    restrict: 'E',
                    replace: true,
                    templateUrl: metUrls('placePeopleListHtml'),
                    scope: {
                        place: '=',
                        people: '=',
                        peopleSelectionList: '=',
                        checkboxCheck: '&'
                    },
                    link: function (scope) {
                        scope.assignSelectedPeople = assignSelectedPeople;
                        scope.groupAndSortPeople = groupAndSortPeople;
                        scope.setPeopleSelectionList = setPeopleSelectionList;
                        scope.groupedPeople = {};
                        scope.personsRendered = false;
                        scope.setEditPerson = setEditPerson;
                        scope.findNameDuplicate = findNameDuplicate;

                        scope.$on('placePeopleListOpened', function (e, placeId) {
                            scope.assignSelectedPeople(placeId);
                            scope.groupedPeople = scope.groupAndSortPeople(placeId);
                            scope.peopleSelectionList = scope.setPeopleSelectionList(placeId);
                        });

                        scope.messages = {
                            noResults: metLocalize('messages', 'noResults'),
                            edit: metLocalize('fieldNames', 'edit')
                        };

                        scope.handleCheckboxCheck = function (person) {
                            scope.checkboxCheck()(person);
                        };

                        scope.updatePerson = function (person) {
                            metPlacePeople.update(person,
                                function (response) {
                                    person.selected = response.selected;
                                    scope.newPersonName = '';
                                },
                                function (error) {
                                    console.log(error);
                                });
                        };

                        function findNameDuplicate(personName) {
                            var nameMatch = function (person) {
                                var re = new RegExp('^' + personName + '$', 'i');
                                return re.test(person.personName);
                            }
                            return scope.people.filter(nameMatch);
                        }

                        function setPeopleSelectionList(placeId) {
                            if (scope.place.placeId === placeId) {
                                if (scope.groupedPeople.false) {
                                    return scope.groupedPeople.true
                                        ? scope.groupedPeople.true.concat(scope.groupedPeople.false)
                                        : scope.groupedPeople.false;
                                }
                                else {
                                    return [];
                                }
                            }
                            else {
                                return [];
                            }
                        }

                        function setEditPerson(person) {
                            scope.person = person;
                            createPlacesEditNameModal(person);
                        }

                        function assignSelectedPeople(placeId) {
                            if (scope.place.placeId === placeId) {
                                _.forEach(scope.people,
                                    function (person) {
                                        if (scope.place.personIds && scope.place.personIds.length) {
                                            return _.find(scope.place.personIds,
                                                function (id) {
                                                    if (id === person.personId) {
                                                        person.selected = true;
                                                        return true;
                                                    }
                                                    else {
                                                        person.selected = false;
                                                        return false;
                                                    }
                                                });
                                        }
                                        else {
                                            person.selected = false;
                                        }
                                        return null;
                                    });
                            }
                        };

                        function groupAndSortPeople(placeId) {
                            if (scope.place.placeId === placeId) {
                                var groupBy = function (objectArray, property) {
                                    return objectArray.reduce(function (acc, obj, idx) {
                                        var key = obj[property];
                                        if (!acc[key]) {
                                            acc[key] = [];
                                        }
                                        obj.index = idx;
                                        acc[key].push(obj);
                                        return acc;
                                    },
                                        {});
                                };
                                return groupBy(scope.people, 'selected');
                            }
                            else {
                                return null;
                            }
                        };

                        function createPlacesEditNameModal(person) {
                            scope.workingPersonName = person.personName;
                            var modalOptions = modalOptionsService.placesEditNameModalOptions;
                            modalOptions.controller = function ($scope, $modalInstance) {
                                $scope.newPersonName = scope.newPersonName;
                                $scope.workingPersonName = scope.workingPersonName;
                                $scope.personModel = person;
                                $scope.place = scope.place;
                                $scope.findNameDuplicate = scope.findNameDuplicate;
                                $scope.duplicatePersonNameo = '';
                                $scope.duplicate = false;
                                $scope.save = save;
                                $scope.cancel = cancel;
                                $scope.placesEditNameInit = placesEditNameInit;

                                $scope.$watch('personModel.personName',
                                    function (newValue) {
                                        var existingPeople = findNameDuplicate(newValue);
                                        if ($scope.personModel) {
                                            var inputContainerId = '#container_' +
                                                $scope.place.placeId +
                                                '_' +
                                                $scope.personModel.personId;
                                            var inputContainer = $(inputContainerId);
                                            if (existingPeople.length > 1) {
                                                $scope.duplicatePersonNameo = existingPeople[1].personName;
                                                $scope.duplicate = true;
                                                $(inputContainer).removeClass('md-input-has-value')
                                                    .addClass('md-input-invalid');
                                            }
                                            else {
                                                $scope.duplicate = false;
                                                $(inputContainer).removeClass('md-input-invalid')
                                                    .addClass('md-input-has-value');
                                            }
                                        }
                                    });

                                function save() {
                                    scope.updatePerson($scope.personModel);
                                    $modalInstance.close();
                                }

                                function cancel(reason) {
                                    scope.person.personName = scope.workingPersonName;
                                    scope.workingPersonName = '';
                                    $modalInstance.dismiss(reason);
                                }

                                function placesEditNameInit() {
                                    $scope.messages = modalOptionsService.placesEditNameModalOptions.messages;
                                }
                            };
                            $modal.open(modalOptions);
                        }


                        scope.finished = function () {
                            scope.personsRendered = true;
                        };
                    }
                };
            }
        ]);
}());
(function() {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metPlacesList',
        [
            '$filter', 'urls', 'localize',
            function($filter,
                metUrls,
                metLocalize) {
                return {
                    restrict: 'E',
                    replace: true,
                    templateUrl: metUrls('placesListHtml'),
                    scope: {
                        loading: '=',
                        places: '=',
                        hasInventoryItems: '=',
                    },
                    link: function(scope) {
                        scope.messages = {
                            noInventory: metLocalize('messages', 'noInventory'),
                            emptyInventoryText: metLocalize('messages', 'emptyInventoryText'),
                            noResults: metLocalize('messages', 'noResults'),
                            noResultsForFilters: metLocalize('messages', 'noResultsForFilters'),
                            clearFilters: metLocalize('commands', 'clearFilters'),
                            projectJob: metLocalize('fieldNames', 'projectJob'),
                            homeBase: metLocalize('fieldNames', 'homeBase'),
                            vehicle: metLocalize('fieldNames', 'vehicle'),
                            all: metLocalize('messages', 'all')
                        }
                    }
                };
            }
        ]);
}());

(function() {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metToolsByCategoryByPlace',
        [
            'urls', 'localize', 'dates', '$modal', 'modalOptionsService', 'stats',
            function(metUrls,
                metLocalize,
                metDates,
                $modal,
                modalOptionsService,
                metStatsService) {
                return {
                    restrict: 'E',
                    replace: true,
                    templateUrl: metUrls('toolsByCategoryByPlaceHtml'),
                    scope: {
                        place: '='
                    },
                    link: function(scope) {
                        scope.metStatsService = metStatsService;
                        scope.seriesName = '';
                        scope.drillupText = '';
                        scope.originalCategoryData = [];
                        scope.otherCategoryData = [];
                        scope.currentSeriesDataObjects = {};
                        scope.tbcPlaceOptions = {};
                        scope.tbcPlaceGraph;
                        scope.messages = {
                            inventoryDashboard: metLocalize('titles', 'inventoryDashboard'),
                            inventoryOverTime: metLocalize('titles', 'inventoryOverTime'),
                            toolsByCategory: metLocalize('titles', 'toolsByCategory'),
                            numberOfTools: metLocalize('fieldNames', 'NumberOfToolsConversational'),
                            reset: metLocalize('commands', 'reset'),
                            other: metLocalize('commands', 'other')
                        };
                        scope.tbcPlaceOptions = {
                            chart: {
                                type: 'pie',
                                renderTo: '',
                                height: 320,
                                events: {
                                    drillup: function () {
                                        updateChartSeries(scope.currentSeriesDataObjects);
                                    }
                                }
                            },
                            credits: {
                                enabled: false
                            },
                            legend: {
                                enabled: false
                            },
                            title: {
                                text: '',
                                y: 20
                            },
                            plotOptions: {
                                pie: {
                                    size: 150,
                                    innerSize: 25,
                                    depth: 20,
                                    showInLegend: false,
                                    startAngle: 270,
                                    dataLabels: {
                                        enabled: true,
                                        connectorPadding: 2,
                                        crop: false,
                                        distance: 10,
                                        softConnector: false,
                                        rotation: 0,
                                        useHtml: true
                                    }
                                },
                                series: {
                                    animation: false
                                }
                            },
                            series: [
                                {
                                    id: 'tbcPlaceData',
                                    name: '',
                                    data: scope.currentSeriesDataObjects,
                                    allowPointSelect: false
                                }
                            ],
                            drilldown: {
                                series: []
                            },
                            loading: false
                        };

                        // -- the Highcharts namespace is exported from the Highcharts library - no other declaration is needed
                        function updateHighchartsLangObject(drilluptext) {
                            Highcharts.setOptions({
                                lang: {
                                    drillUpText: drilluptext
                                }
                            });
                        }

                        scope.$watch('place.isExpanded',
                            function(newValue) {
                                if (newValue) {
                                    scope.refreshGraph(scope.place.placeId);
                                }
                            });

                        scope.refreshGraph = function(placeId) {
                            scope.metStatsService.getToolsByCategoryByPlace(placeId,
                                function(response) {
                                    updateCategoryInfo(response);
                                    setChartOptions(response, placeId);
                                    metLocalize('commands', 'reset').promise.then(function(val) {
                                        scope.drillupText = val;
                                        updateHighchartsLangObject(scope.drillupText);
                                        if (!scope.tbcPlaceGraph) {
                                            scope.tbcPlaceGraph = new Highcharts.Chart(scope.tbcPlaceOptions);
                                        }
                                        updateChartSeries(scope.currentSeriesDataObjects);
                                    });
                                });
                        };

                        // If there are no items assigned to a parent-category but assigned to it's sub-category,
                        // this function groups the sub-categories into it's parent-category 
                        // and adds it to the category list 

                        function updateCategoryInfo(categoryInfo) {
                            var categoryIdList = [];
                            var parentCategoryIdList = [];
                            var seriesData = [];
                            var count = 0;

                            var mainCategory = {
                                categoryName: "",
                                categoryId: "",
                                itemCount: 0,
                                parentCategoryId: null,
                                parentCategoryName: null
                            };

                            var groupedCategories = _.groupBy(categoryInfo.data,
                                function(category) {
                                    return category.parentCategoryId;
                                });

                            _.forEach(categoryInfo.data,
                                function(category) {
                                    categoryIdList.push(category.categoryId);
                                    if (parentCategoryIdList.indexOf(category.parentCategoryId) === -1) {
                                        parentCategoryIdList.push(category.parentCategoryId);
                                    }
                                });

                            _.forEach(parentCategoryIdList,
                                function(id) {
                                    if (id !== null && categoryIdList.indexOf(id) === -1) {
                                        _.forEach(groupedCategories,
                                            function(group) {
                                                if (group[0].parentCategoryId === id) {
                                                    _.forEach(group,
                                                        function(groupItem) {
                                                            count += groupItem.itemCount;
                                                        });

                                                mainCategory = {
                                                    categoryName: group[0].parentCategoryName,
                                                    categoryId: id,
                                                    itemCount: count,
                                                    parentCategoryId: null,
                                                    parentCategoryName: null
                                                };

                                                count = 0;
                                                seriesData = [mainCategory.categoryName, mainCategory.itemCount];

                                                categoryInfo.data.push(mainCategory);
                                                categoryInfo.seriesData.push(seriesData);
                                            }
                                        });
                                    }
                                });

                            return categoryInfo;
                        }

                        function setChartOptions(statsServiceResponse, placeId) {
                            scope.tbcPlaceOptions.chart.renderTo = 'toolsByCategoryByPlaceChartContainer_' + placeId;
                            scope.seriesName = scope.messages.numberOfTools.value;
                            scope.tbcPlaceOptions.title.text = scope.messages.toolsByCategory.value;
                            scope.originalCategoryData = statsServiceResponse.data;
                            scope.currentSeriesDataObjects =
                                setInitialSeriesDataObjects(scope.originalCategoryData);
                            var seriesData = statsServiceResponse.seriesData.sort(function(a, b) {
                                return b[1] - a[1];
                            });
                            scope.tbcPlaceOptions.drilldown.series.length = 0;
                            getDrilldownSeries(scope.currentSeriesDataObjects, seriesData);
                            scope.tbcPlaceOptions.drilldown.series.push(
                                {
                                    "id": -2,
                                    "data": scope.otherCategoryData,
                                    "name": scope.seriesName,
                                    "selected": false,
                                    allowPointSelect: true
                                }
                            );
                            scope.tbcPlaceOptions.series.data = scope.currentSeriesDataObjects;
                        }

                        function getDrilldownSeries(categoryData, seriesData) {
                            return categoryData.map(function(category) {
                                if (category.drilldown && category.id !== -2) {
                                    var retObj = {
                                        "id": category.drilldown,
                                        "name": scope.seriesName,
                                        "data": [],
                                        "selected": false
                                    };
                                    _.forEach(seriesData,
                                        function(item) {
                                            if (item[0] === category.name) {
                                                retObj.data.push(item);
                                            }
                                        });
                                    scope.tbcPlaceOptions.drilldown.series.push(retObj);
                                }
                            });
                        }

                        function setInitialSeriesDataObjects(categoryDataArray) {
                            var getDataLabel = function(categoryName) {
                                if (categoryName.length > 10) {
                                    var label = categoryName.replace(/\s/, '<br/>');
                                    return label;
                                }
                                else {
                                    return categoryName;
                                }
                            }

                            //-- sort descending by item count --
                            categoryDataArray.sort(function(a, b) {
                                return b.itemCount - a.itemCount;
                            });
                            //-- remove sub categories --
                            var workingCategoryDataArray = categoryDataArray.filter(function(category) {
                                return category.parentCategoryId === null;
                            });
                            //-- make the series of objects that Highcharts can read --
                            var workingSeriesDataArray = workingCategoryDataArray.map(function(category) {
                                return {
                                    "id": category.categoryId,
                                    "name": getDataLabel(category.categoryName),
                                    "y": category.itemCount,
                                    "selected": false
                                };
                            });

                            if (workingSeriesDataArray.length >= 10) {
                                var otherCount = 0;
                                var chunks = getArrayChunks(workingSeriesDataArray);
                                _.forEach(chunks.bottom, function(item) { otherCount += item.y });
                                scope.otherCategoryData = chunks.bottom;
                                chunks.top.push({
                                    "id": -2,
                                    "name": scope.messages.other.value,
                                    "y": otherCount,
                                    "drilldown": -2
                                });
                                return chunks.top;
                            }
                            else {
                                return workingSeriesDataArray;
                            }
                        }

                        function updateChartSeries(seriesArray) {
                            var seriesDef = {
                                id: 'tbcPlaceData',
                                name: scope.seriesName,
                                data: seriesArray
                            }
                            if (scope.tbcPlaceGraph.get('tbcPlaceData')) {
                                var seriesData = scope.tbcPlaceGraph.get('tbcPlaceData');
                                seriesData.update(seriesDef, true);
                            }
                        }

                        function getArrayChunks(seriesArray) {
                            //-- The top 9 categories will have labels on the pie chart - the rest may be grouped into 'Other'
                            return {
                                "top": seriesArray.slice(0, 9),
                                "bottom": seriesArray.slice(9, seriesArray.length)
                            };
                        }

                        function openModal() {
                            $modal.open(modalOptionsService.generalErrorModalOptions);
                        }
                    }
                };
            }
        ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.service('locations', ['$resource', 'urls', function ($resource, metUrls) {

        var api = $resource(metUrls('placeApi').concat('/:placeId'),
            {
                placeId: '@placeId'
            },
            {
                'update': { method: 'PUT' },
                'query': { method: 'GET', isArray: false },
                'search': {
                    method: 'GET',
                    url: metUrls('placeApi').concat('/search')
                },
                'migrate': {
                    method: 'POST',
                    isArray: true,
                    url: metUrls('placeApi').concat('/migrate')
                },
                'counts': {
                    method: 'GET',
                    url: metUrls('placeApi').concat('/counts')
                }
            }
        );

        return {
            getAll: function (options, success, error) {
                return api.query(options, success, error);
            },
            getLocation: function (placeId, success, error) {
                return api.get({ placeId: placeId }, success, error);
            },
            update: function (location, success, error) {
                return api.update(location, success, error);
            },
            create: function (location, success, error) {
                return api.save(location, success, error);
            },
            remove: function (location, success, error) {
                return api.remove({ placeId: location.placeId }, success, error);
            },
            search: function (placeFilters, successCallback, errorCallback) {
                return api.search(
                    placeFilters,
                    successCallback,
                    errorCallback
                );
            },
            migrate: function (migrateRequest, successCallback, errorCallback) {
                return api.migrate(
                    migrateRequest,
                    successCallback,
                    errorCallback
                );
            },
            counts: function(successCallback, errorCallback) {
                return api.counts(successCallback, errorCallback);
            }
        };
    }]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.service('people', ['$resource', 'urls', function ($resource, metUrls) {

        var resource = $resource(metUrls('peopleApi').concat('/:personId'),
            {
                personId: '@personId'
            },
            {
                'update': { method: 'PUT' },
                'query': { method: 'GET', isArray: false }
            }
        );

        return {
            getAll: function (options, success, error) {
                return resource.query(options, success, error);
            },
            getPerson: function (personId, success, error) {
                return resource.get({ personId: personId }, success, error);
            },
            update: function (person, success, error) {
                return resource.update(person, success, error);
            },
            create: function (person, success, error) {
                return resource.save(person, success, error);
            },
            remove: function (person, success, error) {
                return resource.remove({ personId: person.personId }, success, error);
            }
        };
    }]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.service('trades', ['$resource', 'urls', function ($resource, metUrls) {

        var resource = $resource(metUrls('tradeApi').concat('/:divisionId'),
            {
                divisionId: '@divisionId'
            },
            {
                'update': { method: 'PUT' },
                'query': { method: 'GET', isArray: false }
            }
        );

        return {
            getAll: function (options, success, error) {
                return resource.query(options, success, error);
            },
            getTrade: function (tradeId, success, error) {
                return resource.get({ tradeId: tradeId }, success, error);
            },
            update: function (trade, success, error) {
                return resource.update(trade, success, error);
            },
            create: function (trade, success, error) {
                return resource.save(trade, success, error);
            },
            remove: function (trade, success, error) {
                return resource.remove({ divisionId: trade.divisionId }, success, error);
            }
        };
    }]);
}());

(function () {
    'use strict';

    var app = angular.module('oneKeyApp');

    app.service('stats', ['$resource', 'urls',
        function ($resource, metUrls) {
            var transfer = $resource(metUrls('statsApi').concat('/transfers'), {},
                {
                    'query': {
                        method: 'GET',
                        isArray: true
                    }
                });

            var counts = $resource(metUrls('statsApi'), {},
                {
                    'query': {
                        method: 'GET'
                    }
                });

            var categoryGraph = $resource(metUrls('statsApi').concat('/categories?groupBy=0'),
                {},
                {
                    'query': {
                        method: 'GET'
                    }
                });
            
            return {
                getTransfers: function (successCallback, errorCallback) {
                    return transfer.query({}, successCallback, errorCallback);
                },
                getTransfersByFilters: function (filterIds, successCallback, errorCallback) {
                    return transfer.query({ filterIds: filterIds }, successCallback, errorCallback);
                },
                getCounts: function (successCallback, errorCallback) {
                    return counts.query({}, successCallback, errorCallback);
                },
                getToolsByCategory: function (categories, successCallback, errorCallback) {
                    return categoryGraph.query({ categories: categories }, successCallback, errorCallback);
                },
                getToolsByCategoryByPlace: function (placeId, successCallback, errorCallback) {
                    return categoryGraph.query({ places: placeId }, successCallback, errorCallback);
                }
            };
        }
    ]);
}());

(function (module) {
    function historyService($http, urls) {
        return {
            getHistoricalData: function () {
                return $http.get(urls('history'))
                    .then(
                    function (result) {
                        result.data.status = result.status;
                        return result.data;
                    },
                    function (error) {
                        return error;
                    }
                );
            },
            getHistoricalDataByPlace: function (placeId) {
                return $http.get(urls('history').concat('/Place/').concat(placeId))
                    .then(
                        function (result) {
                            result.data.status = result.status;
                            return result.data;
                        },
                        function (error) {
                            return error;
                        }
                    );
            }
        };
    }
    module.factory('historyService', historyService);
    historyService.$inject = ['$http', 'urls'];
}(angular.module('oneKeyApp')));
(function() {
    'use strict';

    angular
        .module('oneKeyApp.placeAdd')
        .controller('PlaceAddCtrl', placeAddCtrl);

    placeAddCtrl.$inject = [
        '$window', 'urls', 'dates', 'localize',
        'itemFieldFactory', 'addFormModel', 'domService', '$stateParams', '$state', '$mdDialog', '$scope', 'locations', 'featureToggle'
    ];

    function placeAddCtrl($window,
        metUrls,
        metDates,
        metLocalize,
        metItemFieldFactory,
        addFormModel,
        domService,
        $stateParams,
        $state,
        $mdDialog,
        $scope,
        metPlaces,
        featureToggle) {

        var ctrl = this;
        var placesHome = metUrls('placesIndex');
        featureToggle.getAll()
            .then(function (featuresResponse) {
                ctrl.addPlaceModel.enableGeofence = featuresResponse.geofence
            });

        ctrl.resolveToPopup = true;
        ctrl.errorMsg = null;
        ctrl.includePlaceholder = true;
        ctrl.datePickerOptions = {};
        ctrl.itemFields = metItemFieldFactory;
        ctrl.saving = false;
        ctrl.loadingUserData = true;
        ctrl.datePickerOptions = metDates.getDatePickerOptions();
        var currentDate = moment().startOf('day');
        var minDate = currentDate.toISOString();
        ctrl.datePickerOptions.minDate = ctrl.datePickerOptions ? minDate : null;
        ctrl.format = ctrl.datePickerOptions.format;
        ctrl.now = moment().format(ctrl.datePickerOptions.format);
        ctrl.messages = getMessages();
        ctrl.allPeople = [];
        ctrl.addMode = true;
        ctrl.searchPersonString = '';
        ctrl.selectedPeople = [];
        ctrl.addPlaceModel = {
            divisionId: -1,
            peopleCount: 0,
            personIds: []
        };
        
        ctrl.useMap = 'useMap';
        ctrl.clearAddress = function() {
            ctrl.addPlaceModel.addressLine = '';
            ctrl.addPlaceModel.cityStateZip = '';
            ctrl.addPlaceModel.latitude = undefined;
            ctrl.addPlaceModel.longitude = undefined;
        }
        ctrl.setBackgroundDark = function() {
            domService.loadDarkBackground();
        };

        ctrl.setBackgroundLight = function() {
            domService.loadLightBackground();
        };

        ctrl.isConfirmed = false;
        ctrl.imageUploadUrl = metUrls('imagesUserItemsApi');

        ctrl.reset = function() {
            $window.location.href = placesHome;
        };

        ctrl.addDetail = {
            collapsed: true,
            chevronDirection: 'up'
        };
        ctrl.addPeople = {
            collapsed: true,
            chevronDirection: 'up'
        };
        ctrl.setLocation = {
            collapsed: true,
            chevronDirection: 'up'
        };

        ctrl.collapse = function(target) {
            if (target === 'addDetail') {
                ctrl.addDetail.collapsed = !ctrl.addDetail.collapsed;
                ctrl.addDetail.chevronDirection = !ctrl.addDetail.chevronDirection;
                if (ctrl.addDetail.collapsed === false && ctrl.addPlaceModel.typeId === 2) {
                    setInitialDateDisplay();
                }
            }
            if (target === 'addPeople') {
                ctrl.addPeople.collapsed = !ctrl.addPeople.collapsed;
                ctrl.addPeople.chevronDirection = !ctrl.addPeople.chevronDirection;
            }
            if (target === 'setLocation') {
                ctrl.setLocation.collapsed = !ctrl.setLocation.collapsed;
                ctrl.setLocation.chevronDirection = !ctrl.setLocation.chevronDirection;
            }
        };

        function getMessages() {
            return {
                addProjectJob: metLocalize('titles', 'addProjectJob'),
                endDateConversational: metLocalize('fieldNames', 'endDateConversational'),
                startDateConversational: metLocalize('fieldNames', 'startDateConversational'),
                addHomeBase: metLocalize('messages', 'addHomeBase'),
                addVehicle: metLocalize('messages', 'addVehicle'),
                nameYourPlace: metLocalize('messages', 'nameYourPlace'),
                requiredField: metLocalize('messages', 'requiredField'),
                jobProjectName: metLocalize('messages', 'jobProjectName'),
                homeBaseName: metLocalize('messages', 'homeBaseName'),
                vehicleName: metLocalize('messages', 'vehicleName'),
                division: metLocalize('fieldNames', 'division'),
                addDetail: metLocalize('messages', 'addDetail'),
                startDate: metLocalize('fieldNames', 'startDate'),
                endDate: metLocalize('fieldNames', 'endDate'),
                jobProjectNumber: metLocalize('messages', 'jobProjectNumber'),
                homeBaseNumber: metLocalize('messages', 'homeBaseNumber'),
                vehicleNumber: metLocalize('messages', 'vehicleNumber'),
                phoneNumber: metLocalize('fieldNames', 'phoneNumber'),
                addPeople: metLocalize('messages', 'addPeople'),
                setALocation: metLocalize('messages', 'setALocation'),
                submit: metLocalize('commands', 'submit'),
                cancel: metLocalize('commands', 'cancel'),
                make: metLocalize('fieldNames', 'make'),
                model: metLocalize('fieldNames', 'model'),
                year: metLocalize('fieldNames', 'year'),
                licensePlate: metLocalize('fieldNames', 'licensePlate'),
                yes: metLocalize('commands', 'yes'),
                no: metLocalize('commands', 'no'),
                cancelText: metLocalize('messages', 'cancelInventoryEditConfirmation'),
                useMap: metLocalize('commands', 'useMap'),
                manuallyEnterAddress: metLocalize('commands', 'manuallyEnterAddress'),
                addressLine: metLocalize('fieldNames', 'addressLine'),
                cityStateZip: metLocalize('fieldNames', 'cityStateZip'),
                changeMapEntry: metLocalize('messages', 'changeMapEntry'),
                submissionConfirmation: metLocalize('messages', 'submissionConfirmation'),
                pleaseConfirmSubmission: metLocalize('messages', 'pleaseConfirmSubmission'),
                placeType: metLocalize('fieldNames', 'placeType'),
                details: metLocalize('fieldNames', 'details'),
                setLocation: metLocalize('commands', 'setLocation'),
                setLocationAndGeofence: metLocalize('messages', 'setPlaceLocationAndGeofence'),
                back: metLocalize('commands', 'back'),
                continueSubmit: metLocalize('commands', 'continueSubmit'),
                placeTypeHomeBase: metLocalize('fieldNames', 'placeType_HomeBase'),
                placeTypeProjectJob: metLocalize('fieldNames', 'placeType_ProjectJob'),
                placeTypeUnspecified: metLocalize('fieldNames', 'unassigned'),
                placeTypeVehicle: metLocalize('fieldNames', 'placeType_Vehicle'),
                nonEditableAfterSubmission: metLocalize('messages', 'nonEditableAfterSubmission'),
                searchForAPerson: metLocalize('commands', 'searchForAPerson'),
                selectNamesToAdd: metLocalize('messages', 'selectNamesToAdd'),
                required: metLocalize('fieldNames', 'required'),
                ok: metLocalize('commands', 'ok'),
                error: metLocalize('messages', 'error'),
                geofenceSet: metLocalize('messages', 'geofenceSet')
            }
        }

        if ($stateParams.placeType === null) {
            $state.go('add-place-options');
        }

        if ($stateParams.placeType === 'projectJob') {
            ctrl.addPlaceModel.typeId = 2;
        }
        if ($stateParams.placeType === 'homeBase') {
            ctrl.addPlaceModel.typeId = 3;
        }
        if ($stateParams.placeType === 'vehicle') {
            ctrl.addPlaceModel.typeId = 4;
        }

        ctrl.showConfirm = function(ev) {
            var confirm = $mdDialog.confirm()
                .title(ctrl.messages.cancel.value)
                .content(ctrl.messages.cancelText.value)
                .targetEvent(ev)
                .ok(ctrl.messages.yes.value)
                .parent(angular.element(document.querySelector('#masterForm')))
                .cancel(ctrl.messages.no.value);

            $mdDialog.show(confirm).then(function() {
                // Cancel was confirmed
                $state.go('add-place-options');
            });
        };

        ctrl.showAddressConfirm = function(ev) {
            if (ctrl.addPlaceModel.addressLine ||
                ctrl.addPlaceModel.cityStateZip ||
                ctrl.addPlaceModel.latitude ||
                ctrl.addPlaceModel.longitude) {
                ev.stopImmediatePropagation();
                var confirm = $mdDialog.confirm()
                    .title(ctrl.messages.cancel.value)
                    .content(ctrl.messages.changeMapEntry.value)
                    .targetEvent(ev)
                    .ok(ctrl.messages.yes.value)
                    .parent(angular.element(document.querySelector('#masterForm')))
                    .cancel(ctrl.messages.no.value);

                $mdDialog.show(confirm).then(function() {
                    //Cancel was confirmed
                    ctrl.clearAddress();
                    ctrl.useMap = 'enterManually';
                });
            }
        };

        ctrl.showSubmitConfirm = function(ev) {
            $mdDialog.show({
                    templateUrl: metUrls('sumbitConfirmDialog'),
                    controller: DialogController,
                    parent: angular.element(document.querySelector('#masterForm')),
                    targetEvent: ev,
                    clickOutsideToClose: false,
                    fullscreen: true
                })
                .then(function(answer) {
                    if (answer === 'submit') {
                        if (ctrl.addPlaceModel.startDateTime) {
                            var startDate = metDates.convertLocalToUtc(ctrl.addPlaceModel.startDateTime);
                            ctrl.addPlaceModel.startDate = startDate;
                        }
                        if (ctrl.addPlaceModel.endDateTime) {
                            var endDate = metDates.convertLocalToUtc(ctrl.addPlaceModel.endDateTime);
                            ctrl.addPlaceModel.endDate = endDate;
                        }
                        metPlaces.create(ctrl.addPlaceModel,
                            function() {
                                ctrl.reset();
                            },
                            function(error) {
                                if (error.data.message) {
                                    ctrl.errorMessage = error.data.message;
                                    ctrl.showError(ev);
                                }
                            });
                    }
                });
        };

        function DialogController($scope, $mdDialog) {
            $scope.addPlaceModel = ctrl.addPlaceModel;
            $scope.messages = ctrl.messages;
            $scope.allPeople = ctrl.allPeople;
            $scope.selectedPeople = ctrl.selectedPeople;
            $scope.division = ctrl.itemFields.trades.filter(function(x) {
                return x.divisionId === $scope.addPlaceModel.divisionId;
            });
            if ($scope.division) {
                $scope.divisionName = $scope.division[0].divisionName;
                $scope.divisionId = $scope.division[0].divisionId;
            }

            if ($scope.addPlaceModel.peopleCount > 0) {
                var retrievePersonById = function(id) {
                    return _.find($scope.allPeople, function(person) { return person.personId === id });
                };
                for (var i = 0; i < $scope.addPlaceModel.personIds.length; i++) {
                    if ($scope.selectedPeople.indexOf(retrievePersonById($scope.addPlaceModel.personIds[i])) === -1) {
                        $scope.selectedPeople.push(retrievePersonById($scope.addPlaceModel.personIds[i]));
                    }
                }
            }

            $scope.hide = function() {
                $mdDialog.hide();
            };

            $scope.cancel = function() {
                $mdDialog.cancel();
            };

            $scope.answer = function(answer) {
                $mdDialog.hide(answer);
            };
        }

        function setInitialDateDisplay() {
            if (!ctrl.addPlaceModel.startDate) {
                var startDateElement = document.getElementById('startDateInput');
                if (startDateElement) {
                    startDateElement.value = ctrl.messages.startDateConversational.value;
                }
            }
            if (!ctrl.addPlaceModel.endDate) {
                var endDateElement = document.getElementById('endDateInput');
                if (endDateElement) {
                    endDateElement.value = ctrl.messages.endDateConversational.value;
                }
            }
        }

        ctrl.showError = function(ev) {
            $mdDialog.show(
                $mdDialog.alert()
                .parent(angular.element(document.querySelector('#masterForm')))
                .clickOutsideToClose(false)
                .title(ctrl.messages.error.value)
                .content(ctrl.errorMessage)
                .ariaLabel(ctrl.messages.error.value)
                .ok(ctrl.messages.ok.value)
                .targetEvent(ev)
            );
        };
    }

}());

(function () {
    'use strict';

    var addPlaceDetails = function ($rootScope,
        metUrls,
        addFormModel,
        detailService,
        metLocalize,
        $modal,
        modalOptionsService,
        metDates,
        metTrades) {

        return {
            restrict: 'EA',
            scope: {
                divisions: '=',
                addPlaceModel: '=',
                deleteImage: '&metDeleteImage'
            },
            link: function (scope) {
                scope.startDatePickerOptions = metDates.getDatePickerOptions();
                scope.endDatePickerOptions = metDates.getDatePickerOptions();
                scope.triggerAddNewDivision = triggerAddNewDivision;
                scope.messages = {
                    jobProjectName: metLocalize('messages', 'jobProjectName'),
                    homeBaseName: metLocalize('messages', 'homeBaseName'),
                    vehicleName: metLocalize('messages', 'vehicleName'),
                    endDateConversational: metLocalize('fieldNames', 'endDateConversational'),
                    startDateConversational: metLocalize('fieldNames', 'startDateConversational'),
                    division: metLocalize('fieldNames', 'division'),
                    addDetail: metLocalize('messages', 'addDetail'),
                    startDate: metLocalize('fieldNames', 'startDate'),
                    endDate: metLocalize('fieldNames', 'endDate'),
                    jobProjectNumber: metLocalize('messages', 'jobProjectNumber'),
                    homeBaseNumber: metLocalize('messages', 'homeBaseNumber'),
                    vehicleNumber: metLocalize('messages', 'vehicleNumber'),
                    phoneNumber: metLocalize('fieldNames', 'phoneNumber'),
                    make: metLocalize('fieldNames', 'make'),
                    model: metLocalize('fieldNames', 'model'),
                    year: metLocalize('fieldNames', 'year'),
                    licensePlate: metLocalize('fieldNames', 'licensePlate'),
                    yes: metLocalize('commands', 'yes'),
                    no: metLocalize('commands', 'no'),
                    cancelText: metLocalize('messages', 'cancelInventoryEditConfirmation'),
                    searchOrAdd: metLocalize('commands', 'searchOrAdd'),
                    noResultsFound: metLocalize('messages', 'noResultsFound'),
                    delete: metLocalize('commands', 'delete')
                }

                scope.$watch('addPlaceModel.startDateTime',
                    function (startDate) {
                        if (startDate) {
                            $('#endDateInput').data("DateTimePicker").minDate(startDate);
                        }
                    });

                scope.$watch('addPlaceModel.endDateTime',
                    function (endDate) {
                        if (endDate) {
                            $('#startDateInput').data("DateTimePicker").maxDate(endDate);
                        }
                    });



                scope.isNumberKey = function ($event) {
                    if (isNaN(String.fromCharCode($event.keyCode)) && $event.which !== 8) {
                        $event.preventDefault();
                    }
                }

                scope.firstLetterDivisionGroupFn = function (item) {
                    return item.divisionName.charAt(0).toUpperCase();
                };
                scope.orderFilterFn = function (groups) {
                    return groups;
                };

                scope.onDropDownOpenClose = function (isOpen) {
                    var addButton = document.getElementById('addNewDivision');
                    addButton.style.visibility = isOpen ? 'visible' : 'hidden';
                }
                metTrades.getAll({ includeUnspecified: true },
                    function (data) {
                        scope.divisions = data.items;
                        _.forEach(scope.divisions, function (division) { division.selected = false });
                    });

                function triggerAddNewDivision() {
                    var modalOptions = modalOptionsService.sharedDefaultOptions;
                    modalOptions.templateUrl = metUrls('addTradeModal');
                    var modalInstance = $modal.open(modalOptions);
                    modalInstance.result.then(function (success) {
                        scope.divisions.push(success.toJSON());
                        scope.addPlaceModel.divisionId = success.toJSON().divisionId;
                    });
                }
            },
            templateUrl: metUrls("addPlaceDetails")
        };
    };

    angular.module('oneKeyApp.inventoryAdd')
        .directive('addPlaceDetails', addPlaceDetails);
    addPlaceDetails.$inject = [
        '$rootScope', 'urls', 'addFormModel', 'detailService', 'localize', '$modal', 'modalOptionsService', 'dates', 'trades'
    ];

}());
(function (module) {
    'use strict';

    var addPlaceLandingPage = function (metLocalize, metUrls, addFormModel, itemFields) {
        return {
            restrict: 'E',
            templateUrl: metUrls('addPlaceOptions'),
            scope: {},
            controller: function () {
                var vm = this;

                vm.initialize = function () {
                    vm.addPlace = true;
                    itemFields.init();
                    vm.messages = {
                        jobProject: metLocalize('fieldNames', 'placeType_ProjectJob'),
                        homeBase: metLocalize('fieldNames', 'placeType_HomeBase'),
                        vehicle: metLocalize('fieldNames', 'placeType_Vehicle'),
                        addThisPlaceType: metLocalize('messages', 'addThisPlaceType'),
                        addPlace: metLocalize('messages', 'addPlace'),
                        add: metLocalize('commands', 'add')
                };
                }
            },
            controllerAs: 'vm',
            bindToController: true,
            link: function (scope, element, attrs) {

            }
        }
    }

    module.directive('addPlaceLandingPage', addPlaceLandingPage);
    addPlaceLandingPage.$inject = ['localize', 'urls', 'addFormModel', 'itemFieldFactory'];

}(angular.module('oneKeyApp.placeAdd')));
(function() {

    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('placePeople',
        [
            '$window', 'urls', 'localize', 'people', '$modal', 'modalOptionsService',
            function($window,
                metUrls,
                metLocalize,
                metPeople,
                $modal,
                modalOptionsService) {

                return {
                    restrict: 'E',
                    replace: true,
                    templateUrl: metUrls('placePeople'),
                    scope: {
                        placeModel: '=',
                        allPeople: '=',
                        isAdd: '='
                    },
                    link: function (scope) {
                        scope.assignSelectedPeople = assignSelectedPeople;
                        scope.groupAndSortPeople = groupAndSortPeople;
                        scope.groupedPeople = {};
                        scope.personsRendered = false;
                        scope.searchPersonString = '';
                        scope.workingPersonName = '';
                        scope.newPersonName = '';
                        scope.isPeopleEdit = false;
                        scope.isNewPersonInputEmpty = false;
                        scope.selectedPeople = [];
                        scope.notSelectedPeople = [];
                        scope.workingPeopleArray = [];
                        scope.setEditPerson = setEditPerson;
                        scope.setPeopleEdit = setPeopleEdit;
                        scope.findNameDuplicate = findNameDuplicate;
                        scope.handleNewPersonFormSubmit = handleNewPersonFormSubmit;
                        scope.peopleSelectionList = [];
                        scope.messages = {
                            add: metLocalize('commands', 'add'),
                            addPersonConversational: metLocalize('commands', 'addPersonConversational'),
                            alreadyExists: metLocalize('commands', 'alreadyExists'),
                            assign: metLocalize('commands', 'assign'),
                            assignedPeople: metLocalize('messages', 'assignedPeople'),
                            assignExistingPerson: metLocalize('messages', 'assignExistingPerson'),
                            cancel: metLocalize('commands', 'cancel'),
                            continue: metLocalize('fieldNames', 'continue'),
                            edit: metLocalize('fieldNames', 'edit'),
                            editName: metLocalize('messages', 'editName'),
                            peopleSelected: metLocalize('messages', 'peopleSelected'),
                            personWillBeAdded: metLocalize('messages', 'personWillBeAdded'),
                            required: metLocalize('fieldNames', 'required'),
                            save: metLocalize('commands', 'save'),
                            searchForAPerson: metLocalize('commands', 'searchForAPerson'),
                            selectNamesToAdd: metLocalize('messages', 'selectNamesToAdd'),
                            totalAssignedPeople: metLocalize('messages', 'totalAssignedPeople')
                        };

                        scope.$watch('searchPersonString',
                            function(newValue, oldValue) {
                                if (newValue === '' && oldValue.length) {
                                    scope.setPeopleEdit(true, false);
                                }
                            });

                        scope.searchKeyUp = function (evt) {
                            if (evt.target.value !== '') {
                                var re = new RegExp(evt.target.value, 'gi');
                                var tempArray = scope.allPeople.filter(function (person) { return re.test(person.personName) });
                                scope.peopleSelectionList = tempArray.sort(function (a, b) { return a.index - b.index });
                            }
                        }

                        scope.newPersonKeyUp = function(evt) {
                            var re = new RegExp('\\S', 'g');
                            scope.isNewPersonInputEmpty = re.test(evt.target.value) ? false : true;
                        };

                        scope.handleCheckboxCheck = function(person) {
                            person.selected = !person.selected;
                            scope.updatePerson(person);
                            scope.searchPersonString = '';
                        };

                        scope.updatePerson = function(person) {
                            metPeople.update(person,
                                function(response) {
                                    person.selected = response.selected;
                                    scope.setPeopleEdit(true, false);
                                    updatePeopleCount();
                                    scope.newPersonName = '';
                                },
                                function(error) {
                                    console.log(error);
                                });
                        };

                        scope.addNewPerson = function(newPersonName) {
                            metPeople.create(
                                {
                                    isDeleted: false,
                                    itemCount: 0,
                                    personId: null,
                                    personName: newPersonName
                                },
                                function(response) {
                                    var person = {
                                        isDeleted: response.isDeleted,
                                        itemCount: response.itemCount,
                                        personId: response.personId,
                                        personName: response.personName
                                    };
                                    scope.allPeople.push(person);
                                    scope.handleCheckboxCheck(person);
                                },
                                function(error) {
                                    console.log(error);
                                });
                        };

                        scope.finished = function () {
                            scope.personsRendered = true;
                        };

                        function createPlacesCheckDuplicateNameModal(person) {
                            var modalOptions = modalOptionsService.placesCheckDuplicateNameModalOptions;
                            modalOptions.controller = function($scope, $modalInstance) {
                                $scope.newPersonName = scope.newPersonName;
                                $scope.place = scope.placeModel;
                                $scope.assign = assign;
                                $scope.cancel = cancel;
                                $scope.placesCheckDuplicateNameInit = placesCheckDuplicateNameInit;

                                function assign() {
                                    if (person.selected === false) {
                                        scope.handleCheckboxCheck(person);
                                    }
                                    else {
                                        scope.newPersonName = '';
                                    }
                                    $modalInstance.close();
                                }

                                function cancel(reason) {
                                    scope.newPersonName = '';
                                    $modalInstance.dismiss(reason);
                                }

                                function placesCheckDuplicateNameInit() {
                                    $scope.messages = modalOptionsService.placesCheckDuplicateNameModalOptions.messages;
                                }
                            };
                            $modal.open(modalOptions);
                        };

                        function createPlacesAddPersonModal() {
                            var modalOptions = modalOptionsService.placesAddPersonModalOptions;
                            modalOptions.controller = function($scope, $modalInstance) {
                                $scope.newPersonName = scope.newPersonName;
                                $scope.place = scope.placeModel;
                                $scope.saveAndContinue = saveAndContinue;
                                $scope.cancel = cancel;
                                $scope.placesAddPersonInit = placesAddPersonInit;

                                function saveAndContinue() {
                                    scope.addNewPerson($scope.newPersonName);
                                    $modalInstance.close();
                                }

                                function cancel(reason) {
                                    scope.newPersonName = '';
                                    $modalInstance.dismiss(reason);
                                }

                                function placesAddPersonInit() {
                                    $scope.messages = modalOptionsService.placesAddPersonModalOptions.messages;
                                }
                            };
                            $modal.open(modalOptions);
                        };

                        function createPlacesEditNameModal(person) {
                            scope.workingPersonName = person.personName;
                            var modalOptions = modalOptionsService.placesEditNameModalOptions;
                            modalOptions.controller = function($scope, $modalInstance) {
                                $scope.newPersonName = scope.newPersonName;
                                $scope.workingPersonName = scope.workingPersonName;
                                $scope.personModel = person;
                                $scope.place = scope.placeModel;
                                $scope.findNameDuplicate = scope.findNameDuplicate;
                                $scope.duplicatePersonNameo = '';
                                $scope.duplicate = false;
                                $scope.save = save;
                                $scope.cancel = cancel;
                                $scope.placesEditNameInit = placesEditNameInit;

                                $scope.$watch('personModel.personName',
                                    function(newValue) {
                                        var existingPeople = findNameDuplicate(newValue);
                                        if ($scope.personModel) {
                                            var inputContainerId = '#container_' +
                                                $scope.place.placeId +
                                                '_' +
                                                $scope.personModel.personId;
                                            var inputContainer = $(inputContainerId);
                                            if (existingPeople.length > 1) {
                                                $scope.duplicatePersonNameo = existingPeople[1].personName;
                                                $scope.duplicate = true;
                                                $(inputContainer).removeClass('md-input-has-value')
                                                    .addClass('md-input-invalid');
                                            }
                                            else {
                                                $scope.duplicate = false;
                                                $(inputContainer).removeClass('md-input-invalid')
                                                    .addClass('md-input-has-value');
                                            }
                                        }
                                    });

                                function save() {
                                    scope.updatePerson($scope.personModel);
                                    $modalInstance.close();
                                }

                                function cancel(reason) {
                                    scope.person.personName = scope.workingPersonName;
                                    scope.workingPersonName = '';
                                    $modalInstance.dismiss(reason);
                                }

                                function placesEditNameInit() {
                                    $scope.messages = modalOptionsService.placesEditNameModalOptions.messages;
                                }
                            };
                            $modal.open(modalOptions);
                        };

                        function findNameDuplicate(personName) {
                            var nameMatch = function(person) {
                                var re = new RegExp('^' + personName + '$', 'i');
                                return re.test(person.personName);
                            }
                            return scope.allPeople.filter(nameMatch);
                        };

                        function handleNewPersonFormSubmit() {
                            var existingPersons = findNameDuplicate(scope.newPersonName);
                            if (existingPersons.length) {
                                scope.person = existingPersons[0];
                                createPlacesCheckDuplicateNameModal(scope.person);
                            }
                            else {
                                scope.isNewPersonInputEmpty = !scope.newPersonName.length;
                                if (!scope.isNewPersonInputEmpty) {
                                    createPlacesAddPersonModal();
                                }
                            }
                        };

                        function setEditPerson(person) {
                            scope.person = person;
                            createPlacesEditNameModal(person);
                        };

                        function setPeopleEdit(isPeopleEdit, isCancel) {
                            scope.groupedPeople = groupAndSortPeople();
                            scope.selectedPeople = scope.groupedPeople.true;
                            scope.peopleSelectionList = scope.groupedPeople.false ? scope.groupedPeople.false : [];
                            scope.isPeopleEdit = isPeopleEdit;
                            if (isCancel) {
                                scope.place = scope.placeCopy;
                                scope.placeCopy = {};
                                scope.newPersonName = '';
                            }
                        };

                        function updatePeopleCount() {
                            scope.placeModel.peopleCount = scope.groupedPeople.true.length;
                            scope.placeModel.personIds = [];
                            _.forEach(scope.groupedPeople.true,
                                function (person) {
                                    scope.placeModel.personIds.push(person.personId);
                                });
                        }

                        function assignSelectedPeople() {
                            _.forEach(scope.allPeople,
                                function(person) {
                                    if (scope.placeModel.personIds.length) {
                                        return _.find(scope.placeModel.personIds,
                                            function(id) {
                                                if (id === person.personId) {
                                                    person.selected = true;
                                                    return true;
                                                }
                                                else {
                                                    person.selected = false;
                                                    return false;
                                                }
                                            });
                                    }
                                    else {
                                        person.selected = false;
                                    }
                                    return null;
                                });
                        };

                        function groupAndSortPeople() {
                            var groupBy = function (objectArray, property) {
                                return objectArray.reduce(function (acc, obj, idx) {
                                        var key = obj[property];
                                        if (!acc[key]) {
                                            acc[key] = [];
                                        }
                                        obj.index = idx;
                                        acc[key].push(obj);
                                        return acc;
                                    },
                                    {});
                            };
                            return groupBy(scope.allPeople, 'selected');
                        };

                        var init = function() {
                            metPeople.getAll(null,
                                function(response) {
                                    scope.allPeople = response.items;
                                    assignSelectedPeople();
                                    scope.setPeopleEdit(false, false);
                                },
                                function(error) {
                                    console.log(error);
                                });
                        };

                        init();
                    }
                }

            }
        ]);

}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('uploadPlaceImage', [
        '$compile', '$filter', 'urls', 'localize', 'itemNotes', 'dates', 'uploads', 'Upload', '$timeout', 'notify',
        function ($compile, $filter, metUrls, metLocalize, metItemNotes, metDates, metUploadService, Upload, $timeout, metNotify) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('placeUploads'),
                scope: {
                    imageUrl: '=?',
                    deleteImage: '&deleteImage'
                },
                link: function (scope) {
                    scope.isLoading = true;
                    scope.dateFormat = metDates.date(true);
                    scope.uploads = [];
                    scope.hasImage = false;
                    scope.messages = {
                        save: metLocalize('commands', 'save'),
                        cancel: metLocalize('commands', 'cancel'),
                        edit: metLocalize('fieldNames', 'edit'),
                        remove: metLocalize('fieldNames', 'remove'),
                        uploadedItems: metLocalize('fieldNames', 'uploadedItems'),
                        dragAndDropUpload: metLocalize('commands', 'dragAndDropUpload'),
                        browse: metLocalize('commands', 'browse'),
                        unsupportedUploadFormatImageOrPdf: metLocalize('messages', 'unsupportedUploadFormatImageOrPdf'),
                        unexpectedError: metLocalize('messages', 'unexpectedError'),
                        fileTooLarge: metLocalize('messages', 'fileTooLarge'),
                        replace: metLocalize('commands', 'replace'),
                        delete: metLocalize('commands', 'delete'),
                        dragAndDropNotSupported: metLocalize('messages', 'DragAndDropNotSupported'),
                        imagesWillDisplayOnYourPlacesList: metLocalize('messages', 'ImagesWillDisplayOnYourPlacesList')
                    };

                    scope.uploadUrl = metUrls('imagesUserItemsApi');

                    scope.$watch('files', function () {
                        if (scope.files) {
                            scope.upload(scope.files);
                        }
                    });
                    scope.$watch('file', function () {
                        if (scope.file != null) {
                            scope.upload([scope.file]);
                        }
                    });
                    scope.log = '';

                    scope.upload = function (files) {
                        if (files && files.length) {
                            // We only allow one file to be uploaded at a time here.
                            var file = files[0];
                            if (!file.$error) {
                                if (file.size > 10485760) {
                                    metNotify.error(scope.messages.fileTooLarge.value);
                                    return;
                                }
                                Upload.upload({
                                    url: scope.uploadUrl,
                                    fields: {
                                        'username': scope.username
                                    },
                                    file: file
                                }).progress(function (evt) {
                                    var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                                    scope.log = 'progress: ' + progressPercentage + '% ' +
                                        evt.config.file.name + '\n' + scope.log;
                                }).success(function (data) {
                                    scope.imageUrl = data.imageUrl;
                                    scope.hasImage = true;
                                }).error(function (data) {
                                    metNotify.error(data.message);
                                });
                            }
                            else {
                                if (file.$error === 'pattern') {
                                    metNotify.error(scope.messages.unsupportedUploadFormatImageOrPdf.value);
                                }
                                else {
                                    metNotify.error(scope.messages.unexpectedError.value);
                                }
                            }

                        }
                    };
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    angular
        .module('oneKeyApp.placeMigration')
        .controller('PlaceMigrationCtrl', placeMigrationCtrl);

    placeMigrationCtrl.$inject = [
        '$window', 'urls', 'dates', 'localize'
    ];

    function placeMigrationCtrl($window,
        metUrls,
        metDates,
        metLocalize) {

        var ctrl = this;
        ctrl.messages = getMessages();

        function getMessages() {
            return {
                yes: metLocalize('commands', 'yes'),
                no: metLocalize('commands', 'no'),
                placeTypeHomeBase: metLocalize('fieldNames', 'placeType_HomeBase'),
                placeTypeProjectJob: metLocalize('fieldNames', 'placeType_ProjectJob'),
                placeTypeUnspecified: metLocalize('fieldNames', 'unassigned'),
                placeTypeVehicle: metLocalize('fieldNames', 'placeType_Vehicle'),
                ok: metLocalize('commands', 'ok'),
                error: metLocalize('messages', 'error')
            }
        }
    }

}());

(function (module) {
    'use strict';

    var placeMigrationLandingPage = function (metLocalize, metUrls, addFormModel, metPlaces, $state ,$rootScope) {
        return {
            restrict: 'E',
            templateUrl: metUrls('placeMigration'),
            controller: function () {
                var pmCtrl = this;
                pmCtrl.existingLocationsCount = 0;
                pmCtrl.showMore = false;
                pmCtrl.toggleShowMore = toggleShowMore;
                pmCtrl.toggleCheckBox = toggleCheckBox;
                pmCtrl.backToPlaces = backToPlaces;
                pmCtrl.migrate = migrate;
                pmCtrl.exists = exists;
                pmCtrl.placeTypeToMigrateTo = null;
                function toggleShowMore(showMore) {
                    pmCtrl.showMore = showMore;
                }

                function backToPlaces() {
                    $rootScope.$broadcast('reload-places', {});
                    $state.go('places', {}, { reload: true });
                }

                pmCtrl.unspecifiedLocations = [];
                pmCtrl.selectedLocations = [];
                function toggleCheckBox(place) {
                    var idx = pmCtrl.selectedLocations.indexOf(place);
                    if (idx > -1) {
                        pmCtrl.selectedLocations.splice(idx, 1);
                    }
                    else {
                        pmCtrl.selectedLocations.push(place);
                    }
                };

                function exists(place) {
                    return pmCtrl.selectedLocations.indexOf(place) > -1;
                };

                function migrate() {
                    //var placeIds = pmCtrl.selectedLocations.map(x => x.placeId);
                    var placeIds = pmCtrl.selectedLocations.map(function(x) {
                        return x.placeId;
                    });
                    var request = {
                        placeIds: placeIds,
                        placeTypeId: pmCtrl.placeTypeToMigrateTo
                    };

                    
                    metPlaces.migrate(request,
                        function (response) {
                            pmCtrl.unspecifiedLocations = response;
                            pmCtrl.existingLocationsCount = pmCtrl.unspecifiedLocations.length;
                            pmCtrl.selectedLocations = [];
                            if (pmCtrl.existingLocationsCount > 0) {
                                toastr.options = {
                                    "closeButton": false,
                                    "debug": false,
                                    "newestOnTop": false,
                                    "progressBar": false,
                                    "positionClass": "toast-top-center",
                                    "preventDuplicates": false,
                                    "onclick": null,
                                    "showDuration": "300",
                                    "hideDuration": "1000",
                                    "timeOut": "3500",
                                    "extendedTimeOut": "1000",
                                    "showEasing": "swing",
                                    "hideEasing": "linear",
                                    "showMethod": "fadeIn",
                                    "hideMethod": "fadeOut",
                                    "target": "#migration-container"
                                }
                                toastr['success'](pmCtrl.messages.migrationSuccess.value.format(placeIds.length));
                            } else {
                                $rootScope.$broadcast('reload-places', {});
                                $state.go('places', { successMigration: true, successMigrationMessage: pmCtrl.messages.migrationCompleteSuccess.value },{ reload: true });
                            }
                        },
                        function(error) {
                            console.log(error);
                        });
                }

                pmCtrl.initialize = function () {
                    pmCtrl.addPlace = true;
                    pmCtrl.messages = {
                        jobProject: metLocalize('fieldNames', 'placeType_ProjectJob'),
                        homeBase: metLocalize('fieldNames', 'placeType_HomeBase'),
                        vehicle: metLocalize('fieldNames', 'placeType_Vehicle'),
                        locationsConvertWidget: metLocalize('fieldNames', 'locationsConvertWidget'),
                        existingLocations: metLocalize('messages', 'existingLocations'),
                        placeMigrationIntro: metLocalize('messages', 'placeMigrationIntro'),
                        selectPlaceOption: metLocalize('commands', 'selectPlaceOption'),
                        selectCurrentLocations: metLocalize('messages', 'selectCurrentLocations'),
                        confirmAndSubmit: metLocalize('commands', 'confirmAndSubmit'),
                        backToPlaces: metLocalize('commands', 'backToPlaces'),
                        showMore: metLocalize('commands', 'showMore'),
                        showLess: metLocalize('commands', 'showLess'),
                        aboutProjectJob: metLocalize('messages', 'aboutProjectJob'),
                        aboutHomeBase: metLocalize('messages', 'aboutHomeBase'),
                        aboutVehicle: metLocalize('messages', 'aboutVehicle'),
                        selectLocationsThatApply: metLocalize('commands', 'selectLocationsThatApply'),
                        locationsSelected: metLocalize('messages', 'locationsSelected'),
                        submit: metLocalize('commands', 'submit'),
                        totalProjectJob: metLocalize('messages', 'totalProjectJob'),
                        totalHomeBase: metLocalize('messages', 'totalHomeBase'),
                        totalVehicle: metLocalize('messages', 'totalVehicle'),
                        migrationSuccess: metLocalize('messages', 'migrationSuccess'),
                        migrationCompleteSuccess: metLocalize('messages', 'migrationCompleteSuccess')
                    };

                    pmCtrl.placeOptions = [
                        {
                            placeType: pmCtrl.messages.jobProject,
                            placeTypeId: 2
                        },
                        {
                            placeType: pmCtrl.messages.homeBase,
                            placeTypeId: 3
                        },
                        {
                            placeType: pmCtrl.messages.vehicle,
                            placeTypeId: 4
                        }
                    ];
                    var filters = {
                        removePaging: true,
                        typeIds: [1]
                    };
                    metPlaces.search(filters,
                        function (response) {
                            pmCtrl.unspecifiedLocations = response.places;
                            pmCtrl.existingLocationsCount = pmCtrl.unspecifiedLocations.length;
                        });
                }
            },
            controllerAs: 'pmCtrl',
            bindToController: true,
            link: function (scope, element, attrs) {
                // First, checks if it isn't implemented yet.
                if (!String.prototype.format) {
                    String.prototype.format = function () {
                        var args = arguments;
                        return this.replace(/{(\d+)}/g, function (match, number) {
                            return typeof args[number] != 'undefined'
                                    ? args[number]
                                    : match
                                ;
                        });
                    };
                }
            }
        }
    }

    module.directive('placeMigrationLandingPage', placeMigrationLandingPage);
    placeMigrationLandingPage.$inject = ['localize', 'urls', 'addFormModel', 'locations', '$state', '$rootScope'];

}(angular.module('oneKeyApp.placeMigration')));
(function () {
    'use strict';

    angular
        .module('oneKeyApp.inventoryAdd')
        .controller('InventoryAddCtrl', InventoryAddCtrl);

    InventoryAddCtrl.$inject = ['$log', '$window', '$location', '$timeout', 'Upload', 'urls', 'dates', 'localize', 
                                'itemFieldFactory', 'addFormModel', 'userItems','detailService', 
                                'successSummary', 'domService', '$state', 'notify','$stateParams', 'formModels', '$http', '$filter'];

    function InventoryAddCtrl($log, $window, $location, $timeout, $upload, metUrls, metDates, metLocalize, 
                            metItemFieldFactory, addFormModel, metUserItems, detailService, 
        successSummary, domService, $state, metNotify, $stateParams, formModels, $http, $filter) {

        var ctrl = this;
        var newLocation = _.findWhere(metItemFieldFactory.locations, { placeId: -1 });
        var newPerson = _.findWhere(metItemFieldFactory.people, { personId:-1 });
        var newSerialNumber = '';
        var newToolNumber = '';
        var errorMessage = '';
        var inventoryHome = metUrls('inventoryIndex');

        ctrl.queueCount = 0;
        ctrl.disableFields;
        ctrl.resolveToPopup = true;
        ctrl.errorMsg = null;
        ctrl.detailsQueue = detailService.itemDetailEntries;
        ctrl.includePlaceholder = true;
        ctrl.datePickerOptions = {};
        ctrl.itemFields = metItemFieldFactory;
        ctrl.saving = false;
        ctrl.addFormModel = addFormModel;
        ctrl.displayKit = ctrl.addFormModel.kit.length > 0;
        ctrl.loadingUserData = true;
        ctrl.datePickerOptions = metDates.getDatePickerOptions();
        var currentDate = moment().startOf('day');
        var minDate = currentDate.toISOString();
        ctrl.datePickerOptions.minDate = ctrl.datePickerOptions ? minDate : null;
        ctrl.format = ctrl.datePickerOptions.format;
        ctrl.now = moment().format(ctrl.datePickerOptions.format);
        ctrl.userManufacturers = metItemFieldFactory.manufacturers;
        ctrl.setBackgroundLight = setBackgroundLight;
        ctrl.saveForm = saveForm;
        ctrl.increment = increment;
        ctrl.removeItem = removeItem;
        ctrl.removeKitComponent = removeKitComponent;
        ctrl.removeImage = removeImage;
        ctrl.getKitStatus = getKitStatus;
        ctrl.init = inventoryAddCtrlInit;
        ctrl.purchaseDatePickerOptions = {};
        ctrl.purchaseDatePickerOptions = metDates.getDatePickerOptions();
        ctrl.duplicates = {};
        ctrl.confirmDialogCount = 0;

        ctrl.setBackgroundDark = function () {
            domService.loadDarkBackground();
        };
        
        ctrl.showHideKit = function () {
            ctrl.displayKit = !ctrl.displayKit;   
        };
        
        ctrl.messages = getMessages();

        ctrl.additionalInfoPanel = {
            collapsed: false,
            chevronDirection: 'down'
        };

        ctrl.purchaseInfoPanel = {
            collapsed: true,
            chevronDirection: 'up'
        };

        ctrl.collapse = function (target) {
            if (target === 'additionalInfoPanel') {
                ctrl.additionalInfoPanel.collapsed = !ctrl.additionalInfoPanel.collapsed;
                ctrl.additionalInfoPanel.chevronDirection = !ctrl.additionalInfoPanel.chevronDirection;
                
            }
            if (target === 'purchaseInfoPanel') {
                ctrl.purchaseInfoPanel.collapsed = !ctrl.purchaseInfoPanel.collapsed;
                ctrl.purchaseInfoPanel.chevronDirection = !ctrl.purchaseInfoPanel.chevronDirection;
            }
        };

        var onError = function() {
            ctrl.showSummary = false;
        };

        ctrl.addFormModel.isMilwaukeeTool = addFormModel.isMilwaukeeTool;
        ctrl.addFormModel.imageAlternates = addFormModel.imageAlternates;

        ctrl.showThumbForProductImg;
        ctrl.showThumbForOrderImg;
        ctrl.showThumbForItemizationImg;
        ctrl.isConfirmed = false;

        ctrl.queuedItem = new EmptyDetailModel(newSerialNumber,newToolNumber,newLocation,newPerson,errorMessage);

        ctrl.detailsQueue = [ctrl.queuedItem];
        ctrl.userCategories = metItemFieldFactory.categories;
        ctrl.imageUploadUrl = metUrls('imagesUserItemsApi');
        ctrl.userTrades = metItemFieldFactory.trades;
        ctrl.userLocations = metItemFieldFactory.locations;
        ctrl.userPersons = metItemFieldFactory.people;

        ctrl.primaryManufacturer = _.find(ctrl.userManufacturers,
            function(result) {
                return result.isPrimary;
            });
        
        ctrl.itemCount = ctrl.detailsQueue.length < 1 ? 1 : ctrl.detailsQueue.length;

        ctrl.onProductImgUploaded = function () {
            if (ctrl.addFormModel.productImage != null && ctrl.addFormModel.productImage.length > 0) {
                ctrl.showThumbForProductImg = true;
            }

        };

        ctrl.onOrderInfoImgUploaded = function () {
            if (ctrl.addFormModel.orderInfoImageUrl != null && ctrl.addFormModel.orderInfoImageUrl.length > 0) {
                ctrl.showThumbForOrderImg = true;
            }
        };

        ctrl.onItemizationImgUploaded = function () {
            if (ctrl.addFormModel.itemizationImageUrl != null && ctrl.addFormModel.itemizationImageUrl.length > 0) {
                ctrl.showThumbForItemizationImg = true;
            }
        };
        
        function removeImage(option) {
            if (ctrl.addFormModel !== null) {
                for (var name in ctrl.addFormModel) {
                    if (ctrl.addFormModel.hasOwnProperty(name) && name == option) {
                        ctrl.addFormModel[option] = null;
                        if (option == 'productImage') {
                            ctrl.showThumbForProductImg = false;
                            ctrl.addFormModel.imageAlternates = {};
                        }
                        if (option == 'orderInfoImageUrl') {
                            ctrl.showThumbForOrderImg = false;
                            ctrl.addFormModel.orderInfoImageAlternates = {};
                        }
                        if (option == 'itemizationImageUrl') {
                            ctrl.showThumbForItemizationImg = false;
                            ctrl.addFormModel.itemizationImageAlternates = {};
                        }
                    }
                }
            }
        }

        var itemsToBeAdded = [];

        function mapViewModelToServerModel(viewModel, detailsModel) {

            ctrl.queueCount--;
            if (angular.isDefined(viewModel.kit[1])) {
                ctrl.displayKit = true;
            }
            var manufacturerName = viewModel.manufacturer.manufacturerName;
            var data = {
                manufacturerId: viewModel.manufacturer.manufacturerId,
                modelNumber: viewModel.modelNumber,
                itemDescription: viewModel.description,
                categoryId: angular.isDefined(viewModel.category) ? viewModel.category.categoryId : undefined,
                imageUrl: viewModel.productImage,
                purchaseLocation: viewModel.purchaseLocation,
                orderInformationImageUrl: viewModel.orderInfoImageUrl,
                itemizationImageUrl: viewModel.itemizationImageUrl,
                price : viewModel.value,
                status : viewModel.status,
                notes: viewModel.notes,
                datePurchased: viewModel.purchaseDate && viewModel.purchaseDate.length > 0 ? moment(viewModel.purchaseDate, metDates.date(false)).format(metDates.api) : undefined,
                serviceDate : viewModel.serviceDate && viewModel.serviceDate.length > 0 ? moment(viewModel.serviceDate, metDates.date(false)).format(metDates.api) : undefined,
                divisionId : angular.isDefined(viewModel.division) ? viewModel.division.divisionId : undefined,
                serialNumber: detailsModel.serialNumber,
                toolNumber: detailsModel.toolNumber,
                personId: detailsModel.person.personId,
                placeId: detailsModel.location.placeId,
                isBluetoothCapable: viewModel.isBluetoothCapable,             
                detailsModelId: detailsModel.id
            };
            ctrl.addFormModel.productImage = data.imageUrl;
            var serviceDatePicker = data.serviceDate != null ? moment(data.serviceDate, metDates.shortDateTime.api) : null;
            var purchaseDatePicker = data.purchaseDate != null ? moment(data.purchaseDate, metDates.shortDateTime.api) : null;

            var result = {
                manufacturerName: manufacturerName,
                modelNumber: data.modelNumber,
                description: data.itemDescription
            };

            if (detailsModel.dupe) {
                if (itemsToBeAdded.length === 0) {
                    itemsToBeAdded.push(data);
                } else {
                    var itemDetails = $filter('filter')(itemsToBeAdded, function (item) {return item.detailsModelId === data.detailsModelId} );
                    if (itemDetails.length === 0) {
                        itemsToBeAdded.push(data);
                    }
                } 
            }

            var confirmDialog = $('.jconfirm-box-container').is(':visible');
            ctrl.confirmDialogCount = $('.jconfirm-box-container').length;

            if (!confirmDialog) {
                createUserItem(data, detailsModel);
            }

            if (confirmDialog && ctrl.confirmDialogCount === 1) {
                _.forEach(itemsToBeAdded, function(item) {
                    createUserItem(item, detailsModel);
                });
            }
            
        }

        function createUserItem(item, detailsModel) {
            if (!getKitStatus()) {
                metUserItems.create(item,
                    function (success) {
                        ctrl.saving = false;
                        success.$promise.then(function () {
                            formModels.saveResponse.isSuccess = true;
                            if (ctrl.queueCount <= 0) {
                                redirectToInventory();
                            }
                        });
                    }, function(error) {
                        ctrl.saving = false;
                        formModels.saveResponse.isSuccess = false;
                        ctrl.errorMsg = error.data.message;
                        detailsModel.errorMessage = error.data.message;
                    }
                );
            }
            if (getKitStatus()) {
                metUserItems.create(item,
                    function (success) {
                        success.$promise.then(function() {
                            $stateParams.showForm = false;
                        })
                        
                    }, function (error) {
                        if (angular.isDefined(error.data)) {
                            ctrl.errorMsg = error.data.message;
                        }
                    });
            }
        }

        function redirectToInventory() {
            $state.go('inventory', { success: true });
        }
        function saveForm(viewModel, detailsQueue) {
            ctrl.saving = true;
            for (var i = 0; i < detailsQueue.length; i++) {
                detailsQueue[i].id = i;
                checkForDuplicateValues(viewModel, detailsQueue[i]);
                ctrl.queueCount++;
            }

            if (!getKitStatus()) {
                formModels.saveResponse.isSuccess = true;
                metLocalize('messages', 'inventorySuccessfullyUpdated').promise.then(function (val) {
                    formModels.saveResponse.message = val;
                });
            }
        }

        function checkForDuplicateValues(viewModel, item) {
            var yesText = '',
                noText = '',
                duplicateInfo = '',
                duplicateSN = '',
                duplicateTN = '',
                apiUrl = metUrls('baseApiUrl').concat('/accounts/me/items/exists');

            metLocalize('commands', 'yes').promise.then(function (val) {
                yesText = val;
            });
            metLocalize('commands', 'no').promise.then(function (val) {
                noText = val;
            });
            metLocalize('messages', 'proceedWithDupeSerialNumber').promise.then(function (val) {
                duplicateSN = val;
            });
            metLocalize('messages', 'proceedWithDupeToolNumber').promise.then(function (val) {
                duplicateTN = val;
            });
            metLocalize('titles', 'duplicateInformation').promise.then(function (val) {
                duplicateInfo = val;
            });
            
            $http.get(apiUrl + '?serialNumber=' + item.serialNumber + '&toolNumber=' + item.toolNumber)
                .then(function (response) {
                    ctrl.duplicates = response.data;
                    if (!ctrl.duplicates.serialNumber && !ctrl.duplicates.toolNumber) {
                        mapViewModelToServerModel(viewModel, item);
                    }
                    if (ctrl.duplicates.serialNumber) {
                        $.confirm({
                            title: duplicateInfo,
                            content: duplicateSN,
                            buttons: {
                                yes: {
                                    text: yesText,
                                    action: function () {
                                        item.dupe = true;
                                        mapViewModelToServerModel(viewModel, item);
                                    }
                                },                
                                no: {
                                    text: noText,
                                    action: function () {
                                        ctrl.queueCount--;
                                    }
                                }
                            }
                        })
                    }
                    if (ctrl.duplicates.toolNumber) {
                        $.confirm({
                            title: duplicateInfo,
                            content: duplicateTN,
                            buttons: {
                                yes: {
                                    text: yesText,
                                    action: function () {
                                        item.dupe = true;
                                        mapViewModelToServerModel(viewModel, item);
                                    }
                                },
                                no: {
                                    text: noText,
                                    action: function () {
                                        ctrl.queueCount--;
                                    }
                                }
                            }
                        })
                    } 
                });
        }

        ctrl.reset = function(){
            ctrl.addFormModel = {};
            $window.location.href = inventoryHome;
        };

        function getKitStatus() {
            ctrl.displayKit = ctrl.addFormModel.kit.length > 0;
            return ctrl.displayKit;
        }

        function setBackgroundLight() {
            domService.loadLightBackground();
        }

        function getMessages() {
            return {
                uploadFromSpreadsheet: metLocalize('titles', 'uploadFromSpreadsheet'),
                blankEntryForm: metLocalize('titles', 'blankEntryForm'),
                addMkeTool: metLocalize('titles', 'addMkeTool'),
                createFromExisting: metLocalize('titles', 'createFromExisting'),
                productImage: metLocalize('fieldNames', 'uploadImageHeader'),
                addNewItem: metLocalize('titles', 'addNewItem'),
                required: metLocalize('fieldNames', 'required'),
                generalInfo: metLocalize('titles', 'generalInformation'),
                purchaseInfo: metLocalize('fieldNames', 'purchaseInformation'),
                additionalInfo: metLocalize('titles', 'additionalInfo'),
                addInventory: metLocalize('titles', 'addInventory'),
                editDetails: metLocalize('messages', 'editDetails'),
                editToolDetails: metLocalize('messages', 'editToolDetails'),
                save: metLocalize('commands', 'save'),
                cancel: metLocalize('commands', 'cancel'),
                toolNumber: metLocalize('fieldNames', 'toolNumber'),
                brand: metLocalize('fieldNames', 'manufacturer'),
                modelNumber: metLocalize('fieldNames', 'modelNumber'),
                serialNumber: metLocalize('fieldNames', 'serialNumber'),
                description: metLocalize('fieldNames', 'itemDescription'),
                category: metLocalize('fieldNames', 'categoryId'),
                division: metLocalize('fieldNames', 'divisionId'),
                serviceDate: metLocalize('fieldNames', 'serviceDate'),
                toolPhoto: metLocalize('fieldNames', 'toolPhoto'),
                delete: metLocalize('commands', 'delete'),
                quantity: metLocalize('fieldNames', 'quantityFull'),
                purchaseValue: metLocalize('fieldNames', 'price'),
                datePurchased: metLocalize('fieldNames', 'datePurchased'),
                purchaseLocation: metLocalize('fieldNames', 'purchaseLocation'),
                itemizationImage: metLocalize('fieldNames', 'itemizationImageUrl'),
                orderInfoImage: metLocalize('fieldNames', 'orderInformationImageUrl'),
                searching: metLocalize('messages', 'searchingForYourItem'),
                itemDescription: metLocalize('fieldNames', 'itemDescription'),
                inventorySuccessfullyUpdated: metLocalize('messages', 'inventorySuccessfullyUpdated'),
                addBtn: metLocalize('commands', 'Add'),
                serialNumberExists: metLocalize('messages', 'SerialNumberExists')
            }
        }

        function EmptyDetailModel(serialNumber, toolNumber, location, person, errorMessage) {
            this.serialNumber = serialNumber;
            this.toolNumber = toolNumber;
            this.location = location;
            this.person = person;
            this.errorMessage = errorMessage;
        }

        function increment() {
            ctrl.itemCount++;
            var newDetailsItem = new EmptyDetailModel(newSerialNumber, newToolNumber, newLocation, newPerson, errorMessage);
            ctrl.detailsQueue.push(newDetailsItem);
        }

        function removeKitComponent() {
            if (getKitStatus()) {
                addFormModel.kit.splice($stateParams.selectedIndex, 1);
            }
        }

        function removeItem(index) {
            var itemCount = ctrl.detailsQueue.length;
            if (itemCount !== 1) {
                ctrl.itemCount = itemCount - 1;
                if (!angular.isDefined(index)) {
                    index = itemCount - 1;
                }
                ctrl.detailsQueue.splice(index, 1);
            }
        }

        ctrl.duplicateSerialNumber = false;

        function checkForDuplicateSerialNumbers(itemDetails) {
            var serialNumbersList = [];
            _.forEach(itemDetails, function (item) {
                if (serialNumbersList.indexOf(item.serialNumber.toLowerCase()) === -1) {
                    serialNumbersList.push(item.serialNumber.toLowerCase());
                } else {
                    metLocalize('messages', 'SerialNumberExists').promise.then(function(val) {
                        item.errorMessage = val;
                    });
                    ctrl.duplicateSerialNumber = true;
                }
            });
        }

        ctrl.inventoryAddCtrlInit = inventoryAddCtrlInit;
        function inventoryAddCtrlInit() {
            if (ctrl.addFormModel.division === null) {
                ctrl.addFormModel.division = { divisionId: -1 };
            }
            if (ctrl.addFormModel.category === null) {
                ctrl.addFormModel.category = { categoryId: -1 };
            }
            ctrl.addFormModel.location = { locationId: -1 };
            ctrl.addFormModel.person = { personId: -1 };
            ctrl.addFormModel.serviceDate = "";
            ctrl.addFormModel.orderInfoImageAlternates = {};
            ctrl.addFormModel.orderInfoImageUrl = "";
            ctrl.addFormModel.itemizationImageAlternates = {};
            ctrl.addFormModel.itemizationImageUrl = "";
            ctrl.addFormModel.purchaseLocation = "";
            ctrl.addFormModel.purchaseDate = "";
            ctrl.addFormModel.productImage = addFormModel.imageAlternates.smallUrl;
            ctrl.searching = false;
            ctrl.loadingUserData = false;
            ctrl.disableFields = ctrl.addFormModel.productId !== null && ctrl.addFormModel.productId > 0;
            if ($stateParams.fromState === 'add-new') {
                ctrl.addFormModel = angular.copy(formModels.cleanFormModel);
                ctrl.displayKit = false;
                ctrl.disableFields = false;
            }
            if ($stateParams.fromState === 'search') {
                ctrl.addFormModel.manufacturer = $stateParams.manufacturer;
                ctrl.disableFields = true;
            }
            if ($stateParams.productId > -1 && $stateParams.productId !== null) {
                ctrl.disableFields = true;
            }
            if ($stateParams.fromState === 'existing' && ctrl.addFormModel.manufacturer.isPrimary) {
                ctrl.addFormModel.imageUrl = addFormModel.imageUrl;
                ctrl.disableFields = true;
            }
            if ($stateParams.blankForm) {
                ctrl.addFormModel = angular.copy(formModels.cleanFormModel);
                ctrl.disableFields = false;
            }
            if ($stateParams.redirect) {
                $state.go('add-options');
            }
            if (!$stateParams.showForm){
                ctrl.displayKit = true;
            } else {
                ctrl.displayKit = false;
            }

        }
    }
}());

(function(){
	//this file is not currently being used 
	'use strict';
	
    var diagnosticsController = function(diagnostics) {
        var debug = this;

        debug.alertTypes = diagnostics.alertTypes;
	    debug.alertMessage = '';
        debug.alertType = debug.alertTypes[0];

        debug.createAlert = function() {
            diagnostics.addAlert(debug.alertType, debug.alertMessage);
            debug.alertMessage = '';
            debug.alertType = debug.alertTypes[0];
        };

        debug.createException = function() {
            throw new Error('Error');
		};
    };

    angular.module('oneKeyApp.inventoryAdd').controller('diagnosticsController', diagnosticsController);
}());
(function () {
    'use strict';

    var ExistingSearchCtrl = function ($filter, $state, metSearches, metUserItems, addFormModel, domService, metItemFields, metInventoryFilters, metInventoryGrid, metLocalize, setBackground) {

        var vm = this;
        init();
        vm.messages = {
            addExistingSearchInstructionsRedux: metLocalize('commands', 'addExistingSearchInstructionsRedux'),
            addFromExistingItem: metLocalize('titles', 'addFromExistingItem'),
            resultsFor: metLocalize('fieldNames', 'resultsFor'),
            inventoryToolNumber: metLocalize('fieldNames', 'inventoryToolNumber'),
            modelNumberShort: metLocalize('fieldNames', 'modelNumberShort'),
            modelDescription: metLocalize('fieldNames', 'inventoryGridModelDescription'),
            manufacturer: metLocalize('commands', 'addManufacturer'),
            category: metLocalize('commands', 'addCategory'),
            trade: metLocalize('commands', 'addDivision'),
            searching: metLocalize('messages', 'searchingForYourItem'),
            noMatches: metLocalize('messages', 'noItemsMatchContinueAnyway'),
            add: metLocalize('commands', 'add'),
            search: metLocalize('commands', 'search')
        };

        vm.userManufacturers = metItemFields.manufacturers;
        vm.showResults = false;
        vm.searchResults = {};
        vm.results = {};
        vm.groupedItems = {};
        vm.primaryManufacturer = {};
        vm.selectedManufacturer = {};
        vm.items = [];
        vm.metSearches = metSearches;
        vm.searchTerm = null;
        vm.selected = undefined;
        vm.loading = false;
        vm.itemCount = null;
        vm.addFormModel = addFormModel;
        vm.copy = {};

        vm.showMe = false;

        vm.search = function () {
            if (angular.isDefined(vm.searchTerm) && vm.searchTerm !== null && vm.searchTerm.length > 0) {
                vm.loading = true;
                metInventoryGrid.pageIndex = 0;
                metInventoryFilters.updateFilterResults();
                metInventoryGrid.allItemsSelected = false;
                metInventoryGrid.selectAll();

                var filters = {
                    take: 100,
                    searchTerm: vm.searchTerm
                }

                metUserItems.search(filters, function (response) {
                    response.$promise.then(function (data) {
                        vm.loading = false;
                        vm.showResults = true;
                        vm.itemCount = data.totalCount;
                        vm.groupedItems = data.groupedItems[0];
                        vm.results = angular.copy(data);
                        vm.items = angular.copy(data.groupedItems[0].items);
                        vm.noInventory = vm.totalResults === 0;    
                    });
                    
                });
            } else {
                vm.noInventory = true;
            }
        };
        
        vm.primaryManufacturer = _.find(vm.userManufacturers,
            function (result) {
                return result.isPrimary;
            });

        vm.selectItem = function (item) {
            vm.loading = true;
            var itemsToSelect = [item];
            domService.loadDarkBackground();
            if (item.children && item.children.length > 0) {
                itemsToSelect = item.children;
            }

            vm.addFormModel.manufacturer = _.find(vm.userManufacturers, function (result) {
                return result.manufacturerId === item.manufacturerId;
            });

            vm.addFormModel.modelNumber = item.model;
            vm.addFormModel.description = item.description;
            vm.addFormModel.isBluetoothCapable = item.isBluetoothCapable;
            vm.addFormModel.isMilwaukeeTool = angular.isDefined(vm.addFormModel.manufacturer) ? vm.addFormModel.manufacturer.isPrimary : false;
            getFullUserItem(item.id);
        };

        function getFullUserItem(itemId) {
            metUserItems.get(itemId, function (data) {
                vm.addFormModel.productImage = data.imageUrl;
                vm.addFormModel.imageAlternates = data.imageAlternates;
                vm.addFormModel.productId = data.productId;
                vm.addFormModel.division = data.division;
                vm.addFormModel.category = data.category;
                vm.addFormModel.value = data.price;

                vm.loading = false;
                    $state.go('add-new', { fromState: 'existing', productId: vm.addFormModel.productId });

            }, function () {
                console.log('an error has occurred');
            });
        }

        function init() {
            addFormModel.kit = {};
        }
    };

    angular.module('oneKeyApp.inventoryAdd')
        .controller('ExistingSearchCtrl', ExistingSearchCtrl);
    ExistingSearchCtrl.$inject = ['$filter', '$state', 'searches', 'userItems', 'addFormModel', 'domService', 'itemFieldFactory', 'inventoryFilters', 'inventoryGridConfig', 'localize'];

}());
(function () {
    'use strict';

    var injectables = ['$window', '$filter', 'items', 'urls', 'localize', 'itemFieldFactory', 'dates', 'addFormModel', 'domService', '$state', 'model'];

    var searchController = function ($window, $filter, metItems, metUrls, metLocalize, metItemFields, metDates, addFormModel, domService, $state, model) {

        var ctrl = this;

        var inventoryHome = metUrls('inventoryIndex'),
            host = $window.location.host.split('.');

        host.shift();
        ctrl.addFormModel = model;
        ctrl.addFormModel.manufacturer = _.findWhere(ctrl.userManufacturers, { isPrimary: true });
        ctrl.displayKit = false;
        ctrl.noInventory = false;
        ctrl.selectedKit = {};
        ctrl.displayUrl = host.join('.');
        ctrl.url = (host.length > 0 && host[0].length > 4) ? '//www.' + host.join('.') : '//' + host.join('.');
        ctrl.imageUrl = metUrls('imagesUserItemsApi');
        ctrl.primaryManufacturer = {};
        ctrl.selectedModel = {};
        ctrl.itemCount = 0;
        ctrl.showResults = false;
        ctrl.searchResults = [];
        ctrl.loading = false;
        ctrl.hasSearched = false;
        ctrl.searchTerm = undefined;
        ctrl.selected = undefined;
        ctrl.allResults = [];
        ctrl.showNoResults = false;

        ctrl.messages = {
            searching: metLocalize('messages', 'searchingForYourItem'),
            addMkeTool: metLocalize('titles', 'addMkeTool'),
            tickPairing: metLocalize('messages', 'tickPairing'),
            modelNumber: metLocalize('fieldNames', 'modelNumber'),
            itemDescription: metLocalize('fieldNames', 'itemDescription'),
            search: metLocalize('commands', 'search'),
            resultsFor: metLocalize('fieldNames', 'resultsFor'),
            addBtn: metLocalize('commands', 'Add'),
            addMkeSearchInstructions: metLocalize('commands', 'addMkeSearchInstructions')
        };

        ctrl.datePickerOptions = metDates.getDatePickerOptions();
        ctrl.now = moment().format(ctrl.datePickerOptions.format);
        
        ctrl.trySearch = function(){
            if(angular.isDefined(ctrl.searchTerm) && ctrl.searchTerm !== null && ctrl.searchTerm.length > 0){
                doSearch();
            } else {
                ctrl.noInventory = true;
            }
        }

        ctrl.clearSearchResults = clearSearchResults;
        ctrl.onSearchTermChanged = onSearchTermChanged;

        ctrl.reset = function () {
            ctrl.selectedModel = {};
            ctrl.itemCount = 0;
            ctrl.showResults = false;
            ctrl.searchResults = [];
            ctrl.loading = false;
            ctrl.hasSearched = false;
            ctrl.searchTerm = '';
            ctrl.selected = undefined;
            ctrl.allResults = [];
        };
        
        ctrl.selectItem = function (item) {
            var itemsToSelect = [item];
            domService.loadDarkBackground();
            if (item.children && item.children.length > 0) {
                itemsToSelect = item.children;
            }
            if (angular.isDefined(itemsToSelect[1])) {
                ctrl.displayKit = true;
                ctrl.addFormModel.kit = itemsToSelect;
                addSelectedItemFromKit(ctrl.addFormModel.kit);
                $state.go('add-new', { fromState: 'search', manufacturer: ctrl.primaryManufacturer, showForm: false });
            }
            if (!ctrl.displayKit) {
                ctrl.selectedModel = angular.copy(item);
                ctrl.addFormModel.isMilwaukeeTool = true;
                ctrl.addFormModel.imageAlternates = ctrl.selectedModel.imageAlternates;
                ctrl.addFormModel.manufacturer = ctrl.primaryManufacturer;
                ctrl.addFormModel.modelNumber = ctrl.selectedModel.modelNumber;
                ctrl.addFormModel.description = ctrl.selectedModel.itemDescription;
                ctrl.addFormModel.productImage = ctrl.selectedModel.imageUrl;
                ctrl.addFormModel.isBluetoothCapable = ctrl.selectedModel.isBluetoothCapable;
                $state.go('add-new', { fromState: 'search', manufacturer: ctrl.primaryManufacturer, showForm: true });
                
            }
        }

        function addSelectedItemFromKit(item) {
            ctrl.addFormModel.isMilwaukeeTool = true;
            ctrl.addFormModel.manufacturer = ctrl.primaryManufacturer;
        }

        function doSearch() {
            var searchTerm = ctrl.searchTerm;
            ctrl.showNoResults = false;
            if (!angular.isDefined(searchTerm)) {
                ctrl.showNoResults = true;
                
            } else {
                ctrl.onSearchTermChanged(ctrl.searchTerm);
                ctrl.loading = true;
                metItems.searchItems(searchTerm, 0, 100,
                    function (result) {
                        ctrl.loading = false;
                        ctrl.searchResults = result.items;
                        ctrl.allResults = angular.copy(ctrl.searchResults);
                        ctrl.itemCount = ctrl.allResults.length;
                        ctrl.hasSearched = true;
                        ctrl.showResults = true;
                    },
                    function (result) {
                        ctrl.loading = false;
                        ctrl.searchResults = [];
                        ctrl.hasSearched = true;
                    });
            }
        };

        function clearSearchResults() {
            ctrl.searchResults = [];
            ctrl.searchTerm = null;
            ctrl.itemCount = 0;
            ctrl.showResults = false;
        };

        function onSearchTermChanged(searchTerm) {
            if (!angular.isDefined(searchTerm) || searchTerm === null || searchTerm.length === 0) {
                ctrl.reset();
            }
        };

        ctrl.initialize = function () {
            ctrl.userManufacturers = angular.copy(metItemFields.manufacturers);

            ctrl.primaryManufacturer = _.find(ctrl.userManufacturers,
                function (result) {
                    return result.isPrimary;
                });
            
        }

    };

    angular.module('oneKeyApp.inventoryAdd').controller('searchController', searchController);
    searchController.$inject = injectables;

})();

(function () {
    'use strict';

    var app = angular.module('oneKeyApp.inventoryAdd');

    app.controller('UploadCtrl', [
        '$scope', 'Upload', '$log', '$window', 'notify', 'urls', 'localize', '$state', '$stateParams', 'formModels', 'featureToggle',
        function UploadCtrl($scope, $upload, $log, $window, metNotify, metUrls, metLocalize, $state, $stateParams, formModels, featureToggle) {
            var uploadUrl = metUrls('apiBulkOperations').concat('/upload'),
                templateDownload = metUrls('excelTemplateDownload'),
                inventoryHome = metUrls('inventoryIndex');

            if (_.startsWith(uploadUrl, '/fr')) {
                uploadUrl = uploadUrl.replace('/fr', '');
            }

            $scope.uploadFilename = '';
            $scope.uploading = false;
            $scope.uploadFile = null;
            $scope.uploadErrors = null;
            $scope.uploadRowErrors = null;


            $scope.messages = {
                downloadTemplatePath: metLocalize('excelUpload', 'downloadTemplatePath'),
                unexpectedError: metLocalize('excelUpload', 'UnexpectedError'),
                excelRow: metLocalize('fieldNames', 'excelRow'),
                uploadSuccess: metLocalize('excelUpload', 'UploadSuccess'),
                noFile: metLocalize('excelUpload', 'NoFile'),
                invalidFileType: metLocalize('excelUpload', 'InvalidFileType'),
                uploadTemplate: metLocalize('commands', 'uploadTemplate'),
                downloadTemplate: metLocalize('commands', 'downloadTemplate'),
                excelUploadInstructions1: metLocalize('commands', 'excelUploadInstructionsLineOne'),
                excelUploadInstructions2: metLocalize('commands', 'excelUploadInstructionsLineTwo'),
                excelDownloadInstructions1: metLocalize('commands', 'excelDownloadInstructionsLineOne'),
                excelDownloadInstructions2: metLocalize('commands', 'excelDownloadInstructionsLineTwo'),
                reset: metLocalize('commands', 'reset'),
                save: metLocalize('commands', 'save'),
                addFromSpreadsheet: metLocalize('titles', 'addFromSpreadsheet')
            };

            $scope.fileChanged = function (files) {
                if (files && files.length > 0) {
                    $scope.uploadFile = files[0];
                }
            };

            $scope.fileUpload = function (event) {
                event.stopPropagation();
                event.preventDefault();
                $scope.clearMessages();

                if ($scope.uploading) {
                    return;
                }

                if ($scope.uploadFile) {
                    $scope.uploading = true;

                    $upload.upload({
                        url: uploadUrl,
                        method: 'POST',
                        file: $scope.uploadFile
                    })
                        .success(function (result) {
                            if (angular.isDefined(result.errorMessages) && Object.keys(result.errorMessages).length > 0 ||
                                angular.isDefined(result.rowErrorMessages) && Object.keys(result.rowErrorMessages).length > 0) {
                                //it is actually an error. fileapi.js doesn't recognize 400 Bad Request as an error.
                                // so if we get a message property, and not the one they were looking for, treat it as an error.
                                $scope.uploadErrors = result.errorMessages;
                                $scope.uploadRowErrors = result.rowErrorMessages;
                            } else {
                                if (result.wasBluetoothInstanceAdded) {
                                    localStorage.setItem('displayHowToActiviateToolSecurity', true);
                                }

                                formModels.saveResponse.isSuccess = true;
                                metLocalize('messages', 'inventorySuccessfullyUpdated').promise
                                    .then(function (val) {
                                        formModels.saveResponse.message = val;
                                    }
                                    );
                                $state.go('inventory', { showSuccess: true });
                            }
                            $scope.resetFileUpload();
                        })
                        .error(function (data, status, headers, config) {
                            if (status && status === 400) {
                                $scope.uploadErrors = [$scope.messages.noFile.value];
                            }
                            if (status && status === 415) {
                                $scope.uploadErrors = [$scope.messages.invalidFileType.value];
                            } else {
                                $scope.uploadErrors = [$scope.messages.unexpectedError.value];
                            }
                            $scope.resetFileUpload();
                        });
                }
                else {
                    $scope.uploadErrors = [$scope.messages.noFile.value];
                }
            };
            $scope.clearForm = clearForm;

            $scope.resetFileUpload = function () {
                $scope.uploading = false;
                $scope.uploadFile = null;
            }

            $scope.clearMessages = function () {
                $scope.uploadErrors = null;
                $scope.uploadRowErrors = null;
            };

            String.prototype.splice = function (start, delCount, newSubStr) {
                return this.slice(0, start) + newSubStr + this.slice(start + Math.abs(delCount));
            };

            $scope.init = function () {
                featureToggle.getAll()
                    .then(function (response) {
                        $scope.enableBarcode = response.inventorybarcode;
                        metLocalize('excelUpload', 'downloadTemplatePath').promise.then(function (val) {
                            $scope.path = _.trim(val, '~');
                            if ($scope.enableBarcode) {
                                var indexOfDownloadSlash = getSubstringIndex($scope.path, '/', 2);
                                $scope.path = $scope.path.splice(indexOfDownloadSlash, 0, "/v2");
                            }
                        });
                    });
            }

            function getSubstringIndex(str, substring, n) {
                var times = 0, index = null;
                while (times < n && index !== -1) {
                    index = str.indexOf(substring, index + 1);
                    times++;
                }
                return index;
            }

            function clearForm() {
                $scope.uploading = false;
                $scope.uploadFile = null;
                $scope.clearMessages();
            }

        }]);
}());

(function() {
    'use strict';

    var addFormModel = function() {
        return {
            modelNumber: '',
            description: '',
            productImage: '',
            serviceDate: '',
            manufacturer: {},
            category: {},
            trade: {},
            orderInfoImageUrl: '',
            itemizationImageUrl: '',
            purchaseLocation: '',
            purchaseDate: '',
            value: '',
            isMilwaukeeTool: false,
            imageAlternates: {},				
            orderInfoImageAlternates: {},
            itemizationImageAlternates: {},
            kit: {},
            productId: null
        };   
    };
    
    angular.module('oneKeyApp.inventoryAdd')
        .factory('addFormModel', addFormModel);
}());

(function(){
    'use strict';

	var successSummary = function ($timeout) {

        var summaries = [];

		var showSummary = false;

        var addSummary = function(title, data){
			var summary = { title: title, data: data };
			summaries.push(summary);
	        showSummary = true;
	        //  $timeout(function() {
	        //      dismiss(summary);
			// }, 10000);
	        // showSummary = false;
        };

        var dismiss = function(summary){
            for (var i = 0; i < summaries.length; i++) {
                if (summaries[i] == summary) {
                    summaries.splice(i, 1);
                    break;
                }
            }
		};

        return {
			showSummary: showSummary,
            summaries: summaries,
            addSummary: addSummary,
			dismiss: dismiss
        };
    };

    angular.module('oneKeyApp.inventoryAdd')
        .factory('successSummary', successSummary);
}());
(function() {
    'use strict';


    var diagnostics = function($timeout) {
        
        var currentAlerts = [];
        var alertTypes = ["info", "warning", "success", "danger"];
        
        var addWarning = function (message) {
            addAlert("warning", message);
        };

        var addInfo = function(message) {
            addAlert("info", message);
        };

        var addDanger = function(message) {
            addAlert("danger", message);
        };

        var addSuccess = function(message) {
            addAlert("success", message);
        };

        var addAlert = function(type, message) {
            var alert = { type: type, message: message };
            currentAlerts.push(alert);

            // $timeout(function() {
            //     removeAlert(alert);
            // }, 10000);
        };

        var removeAlert = function(alert) {
            for (var i = 0; i < currentAlerts.length; i++) {
                if (currentAlerts[i] == alert) {
                    currentAlerts.splice(i, 1);
                    break;
                }
            }
        };

        var errorHandler = function(description) {
            return function() {
                addDanger(description);
            };
        };


        return {
            removeAlert: removeAlert,
            addAlert: addAlert,
            errorHandler: errorHandler,
            addInfo: addInfo,
            addWarning: addWarning,
            currentAlerts: currentAlerts,
            alertTypes: alertTypes,
            addSuccess: addSuccess,
            addDanger: addDanger
        };
        
    };
        angular.module('oneKeyApp.inventoryAdd')
                .factory('diagnostics', diagnostics);
})();
(function () {
	'use strict';

	var domService = function () {

		var element = document.getElementById('ok-main-content');

		function checkCurrentBackground(color) {
			if (element !== null){
				return _.includes(element.classList, color);
			}
		}

        var refreshItemCount = function (value) {
            return value;
        };

		var loadLightBackground = function () {
			if (checkCurrentBackground('darker-background')) {
				element.classList.remove('darker-background');
			}
            element.classList.add('light-background');
		};

		var loadDarkBackground = function () {
			if (checkCurrentBackground('light-background')) {
				element.classList.remove('light-background');
			}
			element.classList.add('darker-background');
		};

        return {
            refreshItemCount: refreshItemCount,
			loadLightBackground: loadLightBackground,
			loadDarkBackground: loadDarkBackground
		};

	};
	angular.module('oneKeyApp.inventoryAdd')
		.factory('domService', domService);
})();
(function () {
    'use strict';


    var formModels = function () {

        var cleanFormModel = {
            modelNumber: '',
            description: '',
            productImage: '',
            serviceDate: '',
            manufacturer: {},
            category: { categoryId: -1 },
            trade: { tradeId: -1 },
            orderInfoImageUrl: '',
            itemizationImageUrl: '',
            purchaseLocation: '',
            purchaseDate: '',
            value: '',
            isMilwaukeeTool: false,
            imageAlternates: {},
            orderInfoImageAlternates: {},
            itemizationImageAlternates: {},
            kit: {},
            productId: null
        };

        var saveResponse = {
            isSuccess: null,
            message: ''
        };

        return {
            cleanFormModel: cleanFormModel,
            saveResponse: saveResponse
        };

    };
    angular.module('oneKeyApp.inventoryAdd')
        .factory('formModels', formModels);
})();
(function () {
	'use strict';

	var app = angular.module('oneKeyApp.inventoryAdd');

	var detailService = function() {

        function BlankDetailsModel(serialNumber, toolNumber, location, person, errorMessage) {
            this.serialNumber = serialNumber;
            this.toolNumber = toolNumber;
            this.location = location;
            this.person = person;
            this.errorMessage = errorMessage;
        }

        function getCleanDetailsQueue() {
            var cleanSerialNumber = '';
            var cleanToolNumber = '';
            var cleanLocation = {};
            var cleanPerson = {};
            var cleanDetailsQueue = [];
            var cleanErrorMessage = '';

            var cleanModel = new BlankDetailsModel(cleanSerialNumber, cleanToolNumber, cleanLocation, cleanPerson, cleanErrorMessage);
            cleanDetailsQueue.push(cleanModel);
            return cleanDetailsQueue;
        }

        var itemDetailEntries = [];

        var addEntry = function (model) {
            itemDetailEntries.push(model);
        };

        var removeEntry = function (index) {
			itemDetailEntries.splice(index, 1);
		};

		return {
            itemDetailEntries: itemDetailEntries,
            addEntry: addEntry,
            removeEntry: removeEntry,
            getCleanDetailsQueue: getCleanDetailsQueue
		}
	}

	app.service('detailService', detailService);
}());

(function (module) {
    'use strict';

    var addInventoryLandingPage = function (metLocalize, metUrls, addFormModel, itemFields) {
        return {
            restrict: 'E',
            templateUrl: metUrls('addOptions'),
            scope: {},
            controller: function () {
                var vm = this;

                vm.initialize = function () {
                    vm.addFormModel = addFormModel;
                    itemFields.init();
                    vm.messages = {
                        addInventory: metLocalize('titles', 'addInventory'),
                        uploadFromSpreadsheet: metLocalize('titles', 'uploadFromSpreadsheet'),
                        blankEntryForm: metLocalize('titles', 'blankEntryForm'),
                        addMkeTool: metLocalize('titles', 'addMkeTool'),
                        createFromExisting: metLocalize('titles', 'createFromExisting'),
                    };
                }
            },
            controllerAs: 'vm',
            bindToController: true,
            link: function (scope, element, attrs) {
                
            }
        }
    }

    module.directive('addInventoryLandingPage', addInventoryLandingPage);
    addInventoryLandingPage.$inject = ['localize', 'urls', 'addFormModel', 'itemFieldFactory'];

}(angular.module('oneKeyApp.inventoryAdd')));
(function () {
	'use strict';

	var controller = function($scope, $location, domService){
		var segments = $location.path().split('/');
        $scope.url = segments.slice(-1).pop();

		$scope.$watch('url', function (newValue, oldValue) {
			if (newValue == 'existing'){
				domService.loadLightBackground();
			}
			if ($scope.url == 'search') {
				domService.loadLightBackground();
			}
			else {
				domService.loadDarkBackground();
			}
		});
	};
	controller.$inject = ['$scope', '$location', 'domService'];
	var backgroundColor = function(){
		return {
			restrict:'EA',
			scope: true,
			controller: controller
		};
	};
	
	angular.module('oneKeyApp.inventoryAdd')
	.directive('backgroundColor', backgroundColor);
}());
(function () {
    'use strict';

    var blankTargetLink = function ($window, metUrls) {
        return {
            restrict: 'EA',
            scope: {
                url: '='
            },
            link: function (scope, element, attrs) {
                element.on('click', function () {
                    attrs.target = '_blank';
                    $window.open(scope.url);
                });
            }
        }
    };

    blankTargetLink.$inject = ['$window', 'urls'];

    angular.module('oneKeyApp.inventoryAdd')
        .directive('blankTargetLink', blankTargetLink);    
    
}());
(function () {
    'use strict';


    var oneKeyDiagnostics = function(diagnostics){
        
        return {
            restrict: 'AE',
            template: '<div ng-repeat="alert in currentAlerts" class="alert alert-{{alert.type}}">' +
                        '{{ alert.message }}' +
                            '<div class="close" ng-click="removeAlert(alert)">' +
                                '<span class="glyphicon glyphicon-remove"></span>' +
                            '</div>  '+
                      '</div>',
            scope: true,
            controller: function($scope) {
                $scope.removeAlert = function(alert) {
                    diagnostics.removeAlert(alert);
                };
            },
            link: function(scope) {
                scope.currentAlerts = diagnostics.currentAlerts;
            }
        };
    };

    angular
        .module ('oneKeyApp.inventoryAdd')
        .directive ('oneKeyDiagnostics', oneKeyDiagnostics);

} ());
(function () {

	'use strict';

    var metExistingSearch = function (metUrls) {

		var templateUrl = metUrls('existingSearch');

		return {
			restrict: 'EA',
            scope: {},
            templateUrl: templateUrl,
            controller: 'ExistingSearchCtrl',
            controllerAs: 'existing',
            bindToController: true,
			link: function (scope, elem, attrs) {

				scope.reset = function(searchTerm) {
					scope.showResults = false;
					scope.searchTerm = null;
					scope.searchResults = [];
					scope.items = null;
					scope.results = null;
					scope.itemCount = undefined;

				}
			}
		}
	};
	angular.module('oneKeyApp.inventoryAdd')
		.directive('metExistingSearch', metExistingSearch);
	metExistingSearch.$inject = ['urls'];

}());

(function(module) {
    'use strict';

    var watcherFor = function(form, name) {
        return function() {
            if (name && form[name]) {
                return form[name].$invalid;
            }
        };
    };

    var updaterFor = function(element) {
        return function(hasError) {
            if (hasError) {
                element.removeClass("")
                    .addClass("");
            } else {
                element.addClass("")
                    .removeClass("");
            }
        };
    };

    var setupDom = function(element) {
        var input = element[0].querySelector("input, textarea, select, text");
        var type = input.getAttribute("type") !== undefined ? input.getAttribute("type") : null;
		var name = input.getAttribute("name");
        if (type !== "checkbox" && type !== "radio") {
            input.classList.add("form-control");
        }
        var label = element[0].querySelector("label");
        if (label){
            label.classList.add("control-label");    
        }
        
        return name;
    };

    //var addMessages = function(form, element, name, $compile, scope) {
    //    var messages = "<div class='help-block' ng-messages='" +
    //        form.$name + "." + name + ".$error" +
    //        "' ng-messages-include='templates/messages.html'><div>";
    //    element.append($compile(messages)(scope));
    //};

    var link = function($compile) {
        return function(scope, element, attributes, form) {
            var name = setupDom(element);
            //addMessages(form, element, name, $compile, scope);
            scope.$watch(watcherFor(form, name), updaterFor(element));
        }
    };

    var forminput = function($compile) {

        return {
            restrict: "A",
            require: "^form",
            link: link($compile)
        };

    };

    module.directive("forminput", forminput);

}(angular.module("oneKeyApp.inventoryAdd")));
(function() {

	var link = function(scope, element, attrs) {
		scope.collapsed = false;
		scope.collapse = function() {
			scope.collapsed = !scope.collapsed;
		};
		
	}

	var okGeneralInfoPane = function(metUrls) {
		return {
			templateUrl: metUrls('inventoryAddFormPane'),
			scope: {
				manufacturers: '=',
				model: '='
			},
			link: link

		};
	};


	angular.module('oneKeyApp.inventoryAdd')
		.directive('okGeneralInfoPane', okGeneralInfoPane);

	okGeneralInfoPane.$inject = ['urls'];
}());
  //(function (module) {

  //	module.config(function ($provide) {
  //		$provide.decorator('$interpolate', function ($delegate, $log) {

  //			var serviceWrapper = function () {
  //				var bindingFunction = $delegate.apply(this, arguments);
  //                  if (angular.isFunction(bindingFunction) && arguments[0]) {
                        
  //        			    return bindingWrapper(bindingFunction, arguments[0].trim());
                        
  //                  }
                    
  //				return bindingFunction;
  //			};

  //              var bindingWrapper = function (bindingFunction, bindingExpression) {
  //                  return function () {
  //                      var result = bindingFunction.apply(this, arguments);
  //                      var trimmedResult = result.trim();
  //                      var isTranslation = bindingExpression.split('.')[0].includes('messages') ||
  //                          (angular.isDefined(bindingExpression.split('.')[1] &&
  //                              bindingExpression.split('.')[1].includes('messages'))) ? true : false;

  //                      var log = trimmedResult ? $log.info : $log.warn;
  //                      if (isTranslation) {
  //                          log.call($log, 'TRANSLATION = ' + bindingExpression + ' : ' + trimmedResult);
  //                      }
  //                      if (!isTranslation) {
  //                          log.call($log, bindingExpression + ' = ' + trimmedResult);
  //                      }
                        

  //                      //log.call($log, bindingExpression);
  //                      //log.call($log, trimmedResult);
  //                      return result;

  //                  }
  //              }
  //		angular.extend(serviceWrapper, $delegate);
  //		return serviceWrapper;

  //		});
  //	});

  //}(angular.module('oneKeyApp.inventoryAdd')));
(function() {
	'use strict';

	var addDetailsPane = function($rootScope, metUrls, addFormModel, detailService, metLocalize, metItemFieldFactory) {

			return {
				restrict: 'EA',
				scope: {
					locations: '=?',
					people: '=?',
					detailsQueue: '=',
					index: '@',
					addItem: '&',
                    removeItem: '&',
                    inputError: '=?'
                },
                link: function (scope, element, attrs) {
                    scope.itemFields = metItemFieldFactory;
                    scope.messages = {
                       serialNumber : metLocalize('titles', 'serialNumber'), 
                       itemDetails : metLocalize('commands', 'itemDetails'), 
                       toolNumber : metLocalize('fieldNames', 'toolNumber'), 
                       place : metLocalize('fieldNames', 'placeId'),
					   addPerson : metLocalize('titles', 'addPerson'),
                       serialNumberRequired: metLocalize('messages', 'serialNumberRequired'),
                       toolOwned: metLocalize('messages', 'toolAlreadyOwnedMessage')
                    }
                    scope.includePlaceholder = true;
                    scope.count = scope.detailsQueue.length;
                    scope.tabindices = [14, 15, 16, 17];
                    scope.canRemove = function () {
                        return scope.detailsQueue.length > 1;
                    };
                    scope.currentLocation = metItemFieldFactory.nullLocation;
                    scope.currentPerson = metItemFieldFactory.nullPerson;
                    scope.useModal = true;
                    scope.serialNumberError = false;

                    var duplicateModelNumbers_OneKey =  ['2672-20', '2633-20', 'M18 HCC-0', 'M18 BLPXPL-0', 'M18HCC-0'];

                    for (var i = 0; i < duplicateModelNumbers_OneKey.length; i++) {
                        if (addFormModel.modelNumber === duplicateModelNumbers_OneKey[i] && addFormModel.isBluetoothCapable) {
                            scope.serialNumberError = true;
                        }
                    }
                },
				templateUrl: metUrls("addDetailsPane")
			};
		};

	angular.module('oneKeyApp.inventoryAdd')
		.directive('addDetailsPane', addDetailsPane);
	addDetailsPane.$inject = ['$rootScope', 'urls', 'addFormModel', 'detailService', 'localize', 'itemFieldFactory'];

}());
(function () {
    'use strict';

    var app = angular.module('oneKeyApp');

    app.directive('metImageUploader', ['Upload', '$log', 'notify', 'localize', function ($upload, $log, metNotify, metLocalize) {
        return {
            restrict: 'E',
            scope: {
                ngModel: '=',
                ngModelList: '=',
                metModelAlternates: '=',
                metUploadUrl: '@',
                metUploadAllowPdfs: '=',
                metOnFileUploaded: '=',
                metThumbDefault: '=',
                metDefaultImage: '=',
                metForceImage: '=',
                metShowThumb: '@',
                metImageDetailPosition: '@',
                metDisableSave: '=?',
                metDisabled: '=?',
                metRemoveFile: '&?'
            },
            template:
            '<div>'+
            '<a class="onekey-button-img-lightblue" data-ng-class="{\'image-upload-with-thumb\':showThumbnail}" data-ng-show="!metDisabled" ngf-select="fileChanged($files)" accept="image/*" tabindex="$index">' +
            '   <span class="icon icon-camera2 camera-icon-inner"></span> ' +
            '<p class="img-text">{{ upload.value }} {{ image.value }}</p>' +
            '<div class="loading" data-ng-show="uploadingImage"><i class="fa fa-spinner fa-spin"></i></div>' +
                '<div data-ng-if="!canUpload">' +
                    '<a href="https://www.adobe.com/go/getflashplayer" target="_blank" border="0"><img src="/content/images/get_flash_player.jpg"/></a>' +
                '</div>' +
            '</a></div>',
            replace: true,
            link: function (scope, element, attrs) {
                scope.buttonText = metLocalize('commands', 'UploadFile');
                scope.removeLink = metLocalize('commands', 'Remove');
                scope.unexpectedError = metLocalize('messages', 'unexpectedError');
                scope.installFlashToUpload = metLocalize('messages', 'installFlashToUpload');
                scope.upload = metLocalize('commands', 'upload');
                scope.image = metLocalize('fieldNames', 'image');

                scope.fallback = angular.isDefined(FileAPI.hasFlash) && FileAPI.hasFlash;
                scope.canUpload = !angular.isDefined(FileAPI.hasFlash) || FileAPI.hasFlash;

                scope.initialImg = scope.metForceImage ? scope.ngModel : "";
                scope.initialAlts = scope.metForceImage ? scope.metModelAlternates : "";
                scope.fileUploaded = false;

                scope.showThumbnail = angular.isDefined(attrs.metShowThumb);

                var hasDisableSave = attrs.metDisableSave;

                scope.showRemoveLink = function () {
                   
                    var show = scope.ngModel;
                    if (scope.metForceImage)
                        show = scope.fileUploaded;
                    if (scope.ngModel === scope.metDefaultImage)
                        show = false;
                    return show;
                }

                scope.removeFile = function () {
                    scope.ngModel = "";
                    scope.metModelAlternates = "";

                    scope.fileUploaded = false;
                    if (scope.metOnFileUploaded) {
                        scope.$eval(scope.metOnFileUploaded);
                    }

                    if ('ngModelList' in attrs) {
                        for (var i = 0; i < scope.ngModelList.length; i++) {
                            scope.ngModelList[i].imageUrl = "";
                            scope.ngModelList[i].imageAlternates = "";
                        }
                    }
                }

                scope.fileChanged = function (files) {
                    if (files != null && files.length > 0) {
                        scope.uploadingImage = true;
                        if (hasDisableSave) {
                            scope.metDisableSave = true;
                        }

                        $upload.upload({ 
                            url: scope.metUploadUrl,
                            method: 'POST',
                            file: files[0]
                        }).success(function(result) {
                            if (angular.isDefined(result.message) && !angular.isDefined(result[scope.metUploadModelPropertyActual])) {
                                //it is actually an error. fileapi.js doesn't recognize 400 Bad Request as an error.
                                // so if we get a message property, and not the one they were looking for, treat it as an error.
                                metNotify.error(result.message);
                            } else {
                                scope.ngModel = result['imageUrl'];
                                scope.metModelAlternates = result['imageAlternates'];
                                scope.fileUploaded = true;
                                if (scope.metOnFileUploaded) {
                                    scope.$eval(scope.metOnFileUploaded);
                                }

                                // upload the given list of models if given a list (batch update child detail images)
                                if ('ngModelList' in attrs) {
                                    for (var i = 0; i < scope.ngModelList.length; i++) {
                                        scope.ngModelList[i].imageUrl = result['imageUrl'];
                                        scope.ngModelList[i].imageAlternates = result['imageAlternates'];
                                    }
                                }
                            }
                            scope.uploadingImage = false;
                            if (hasDisableSave) {
                                scope.metDisableSave = false;
                            }
                        }
                        ).error(function (e) {
                            if (angular.isDefined(e) && angular.isDefined(e.message)) {
                                metNotify.error(e.message);
                            } else {
                                metNotify.error(scope.unexpectedError.value);
                            }
                            scope.uploadingImage = false;
                            if (hasDisableSave) {
                                scope.metDisableSave = false;
                            }
                        });
                    }
                };
                scope.uploadingImage = false;
                scope.uploadFile = null;
            }


        }
    }]);
}());

(function () {
    'use strict';

    var selectedState = function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                element.bind('focus', function () {
                    element.addClass('border-active');
                }).bind('blur', function () {
                    element.removeClass('border-active');
                 });

                scope.$watch('attrs.tabindex', function () {
                    element.on('focus', function () {
                        element.addClass('border-active');
                        
                    })
                })
            }
        }
    }

    var app = angular.module('oneKeyApp.inventoryAdd');
    app.directive('selectedState', selectedState);
}());

(function () {
    'use strict';

    var selectFromKit = function ($window, $state, $stateParams, metUrls, addFormModel) {
        var templateUrl = metUrls('selectFromKit');
        return {
            restrict: 'AE',
            scope: {
                messages: '=',
                displayKit: '&',
                removeKitComponent: '&',
                metItemCount: '=',
                kitComponentManufacturer: '='
            },
            templateUrl: templateUrl,
            link: function (scope) {
                var inventoryHome = metUrls('inventoryIndex');
                scope.addFormModel = addFormModel;
                scope.addFormModel.kit = addFormModel.kit;
                scope.select = function (item, index) {
                    scope.addFormModel.isMilwaukeeTool = true;
                    scope.addFormModel.imageAlternates = item.imageAlternates;
                    scope.addFormModel.modelNumber = item.modelNumber;
                    scope.addFormModel.description = item.itemDescription;
                    scope.addFormModel.productImage = item.imageUrl;
                    scope.addFormModel.isBluetoothCapable = item.isBluetoothCapable;
                    scope.metItemCount = 1;
                    showHideKit();
                    $state.go('add-new', { fromState: 'search', manufacturer: scope.addFormModel.manufacturer, showForm: true, selectedIndex: index });
                }

                scope.goHome = function () {
                    $window.location.href = inventoryHome;
                }

                function showHideKit() {
                    scope.displayKit();
                }
            }
        }
    };

    angular.module('oneKeyApp.inventoryAdd')
        .directive('selectFromKit', selectFromKit);
    selectFromKit.$inject = ['$window', '$state', '$stateParams', 'urls', 'addFormModel'];
}());
(function () {
    'use strict';

    var app = angular.module('oneKeyApp');

    app.service('itemNotes', ['$resource', 'urls',
        function ($resource, metUrls) {

            var resource = $resource(
                metUrls('itemNotesApi')
            );

            var resourceById = $resource(metUrls('itemNotesApi').concat('/:id'),
                {
                    id: '@id'
                },
                {
                    'update': { method: 'PUT' }
                }
            );

            return {
                get: function (userItemId, successCallback, errorCallback) {
                    return resource.get({
                        userItemId: userItemId
                    },
                        successCallback,
                        errorCallback
                    );
                },
                create: function (note, successCallback, errorCallback) {
                    return resource.save(
                        note,
                        successCallback,
                        errorCallback
                    );
                },
                edit: function (note, successCallBack, errorCallback) {
                    return resourceById.update(note, successCallBack, errorCallback);
                },
                remove: function (note, success, error) {
                    return resourceById.remove({ id: note.id }, success, error);
                }
            }
        }
    ]);
}());
(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.factory('itemFieldFactory', ['$rootScope', 'categories', 'trades', 'people', 'locations', 'manufacturers', 'itemStatuses',
        function ($rootScope, metCategories, metTrades, metPeople, metLocations, metManufacturers, metStatuses) {

        var service = {};
        service.categories = [];
        service.parentCategories = [];
        service.nullCategory = {};
        service.locations = [];
        service.nullLocation = {};
        service.people = [];
        service.nullPerson = {};
        service.manufacturers = [];
        service.trades = [];
        service.nullTrade = {};
        service.statuses = [];
        service.values = [];

        service.init = function () {
            this.loadCategories();
            this.loadTrades();
            this.loadPeople();
            this.loadLocations();
            this.loadManufacturers();
            this.loadStatuses();
        };
        
        service.loadCategories = function () {
            metCategories.getAll({
                includeUncategorized: true
            },
                function (data) {
                    var categories = [];
                    service.parentCategories = [];
                    _.forEach(data.items, function (category) {
                        category.displayName = category.categoryName;
                        categories.push(category);
                        service.parentCategories.push(category);
                        _.forEach(category.childCategories, function (childCategory) {
                            childCategory.displayName = childCategory.categoryName;
                            childCategory.categoryName = "--  " + childCategory.categoryName; // <--- COMPLETE HACK, but will do for now until we decide exact UI
                            categories.push(childCategory);
                        });
                    });

                    service.categories = categories;
                    $rootScope.$broadcast("list-updated", { name: "category", items: service.categories });
                });
            service.nullCategory = _.findWhere(service.categories, {
                categoryId: -1
            });
        }

        service.loadTrades = function () {
            metTrades.getAll({
                includeUnspecified: true
            },
                function (data) {
                    _.forEach(data.items, function (trade) {
                        service.trades = data.items;
                    });

                    $rootScope.$broadcast("list-updated", { name: "division", items: service.trades });
                });

            service.nullTrade = _.findWhere(service.trades, {
                divisionId: -1
            });
        }

        service.loadPeople = function () {
            metPeople.getAll({
                includeUnspecified: true
            },
                function (data) {
                    _.forEach(data.items, function (person) {
                        service.people = data.items;
                    });

                    $rootScope.$broadcast("list-updated", { name: "person", items: service.people });
                });
            service.nullPerson = _.findWhere(service.people, {
                personId: -1
            });
        }

        service.loadLocations = function () {
            metLocations.getAll({
                includeUnspecified: true,
                forAssignment: true
            },
                function (data) {
                    _.forEach(data.items, function (value) {
                        service.locations = data.items;
                    });

                    $rootScope.$broadcast("list-updated", { name: "place", items: service.locations });
                });
            service.nullLocation = _.findWhere(service.locations, {
                placeId: -1
            });
        }

        service.loadManufacturers = function () {
            metManufacturers.getAll(function (data) {
                _.forEach(data.items, function (value) {
                    service.manufacturers = data.items;
                });

                $rootScope.$broadcast("list-updated", { name: "manufacturer", items: service.manufacturers });
            });
        };

        service.loadStatuses = function () {
            metStatuses.getAll(function (data) {
                _.forEach(data.items, function (value) {
                    service.statuses = data.items;
                });

                $rootScope.$broadcast("list-updated", { name: "status", items: service.statuses });
            });
        };

        return service;
    }]);
}());

(function() {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.service('categories', ['$resource', 'urls', function($resource, metUrls) {
        
        var resource = $resource(metUrls('categoryApi').concat('/:categoryId'),
        {
            categoryId: '@categoryId'
        }, 
        {
            'update': {
                method: 'PUT'
            },
            'query': {
                method: 'GET',
                isArray: false
            }
        });

        return {
            getAll: function (options, success, error) {
                return resource.query(options, success, error);
            },
            getCategory: function(categoryId, success, error) {
                return resource.get({
                    categoryId: categoryId
                }, success, error);
            },
            update: function(category, success, error) {
                return resource.update(category, success, error);
            },
            create: function(category, success, error) {
                return resource.save(category, success, error);
            },
            remove: function(category, success, error) {
                return resource.remove({
                    categoryId: category.categoryId
                }, success, error);
            }
        };
    }]);
}());
(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.service('uploads', ['$resource', 'urls', function ($resource, metUrls) {

        var api = $resource(metUrls('uploadsApi').concat('/:userItemId'),
            {
                userItemId: '@userItemId'
            },
            {
                'update': { method: 'PUT' },
                'query': { method: 'GET', isArray: true}
            }
        );

        var apiUpdate = $resource(metUrls('uploadsApi').concat('/:id'),
            {
                id: '@id'
            },
            {
                'update': { method: 'PUT' },
                'query': { method: 'GET', isArray: true }
            }
        );

        return {
            getUploads: function (userItemId, success, error) {
                return api.query({ userItemId: userItemId }, success, error);
            },
            update: function (userItemResource, success, error) {
                return apiUpdate.update(userItemResource, success, error);
            },
            create: function (location, success, error) {
                return api.save(location, success, error);
            },
            remove: function (userItemResourceId, success, error) {
                return api.remove({ userItemId: userItemResourceId }, success, error);
            }
        };
    }]);
}());

(function () {
    'use strict';

    var app = angular.module('oneKeyApp');

    app.service('manufacturers', ['$resource', 'urls', function ($resource, metUrls) {
        var resource = $resource(metUrls('manufacturersApi').concat('/:manufacturerId'),
            {
                manufacturerId: '@manufacturerId'
            },
            {
                'update': {
                    method: 'PUT'
                },
                'query': {
                    method: 'GET',
                    isArray: false,
                    params: {
                        'includeGlobalManufacturers': true
                    }
                }
            });

        return {
            getAll: function (success, error) {
                return resource.query(null, success, error);
            },
            get: function (manufacturerId, success, error) {
                return resource.get({ manufacturerId: manufacturerId }, success, error);
            },
            update: function (manufacturer, success, error) {
                return resource.update(manufacturer, success, error);
            },
            create: function (manufacturer, success, error) {
                return resource.save(manufacturer, success, error);
            },
            remove: function (manufacturer, success, error) {
                return resource.remove({ manufacturerId: manufacturer.manufacturerId }, success, error);
            }
        };
    }]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.service('itemStatuses', ['$resource', 'urls', function ($resource, metUrls) {

        var resource = $resource(metUrls('statusApi'),
        { },
        {
            'query': {
                method: 'GET',
                isArray: false
            }
        });

        return {
            getAll: function (success, error) {
                return resource.query({}, success, error);
            }
        };
    }]);
}());
