(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);
            }
        };
    }]);
}());
(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 () {
    '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 oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.service('serviceRecordUploads', ['$resource', 'urls', function ($resource, metUrls) {

        var apiUpdate = $resource(metUrls('serviceRecordUploadsApi').concat('/:id'),
            {
                id: '@id'
            },
            {
                'update': { method: 'PUT' },
                'query': { method: 'GET', isArray: true }
            }
        );

        return {
            update: function (serviceRecordUpload, success, error) {
                return apiUpdate.update(serviceRecordUpload, success, error);
            },
            remove: function (serviceRecordUploadId, success, error) {
                return apiUpdate.remove({ id: serviceRecordUploadId }, success, error);
            }
        };
    }]);
}());

(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('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 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('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 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('inventory', [
        '$resource', 'urls', function($resource, metUrls) {

            var searchResource = $resource(metUrls('inventorySearch'));
            var bulkUpdateResource = $resource(metUrls('inventoryBulkUpdate'));
            var itemStatuses = $resource(metUrls('itemStatusList'));
            var apiResource = $resource(metUrls('userItemsApi').concat('/:userItemId'),
            { userItemId: '@itemId' },
            {
                'update': { method: 'PUT', }
            });
            var categoryTotals = $resource(metUrls('inventoryCategoryItemTotals'));
            var milwaukeeDefaultUrl = metUrls('milwaukeeDefault');
            var otherDefaultUrl = metUrls('otherDefault');
            var lockResource = $resource(metUrls('securityApi').concat('/:productId/instances/:serialNumberId/toolsecurity/secure/pending'),
                { productId: '@product',  serialNumberId: '@serialNumber' },
            {
                'update': { method: 'PUT' }
            });

            var updateSecurityResource = $resource(metUrls('userSettingsApi').concat('/toolsecurity'), {}, {
                'save': { method: 'POST' }
            });

            return {
                getUserItems: function (searchFilters, callback) {
                    return searchResource.get(searchFilters, callback);
                },
                update: function (userItem, successCallback, errorCallback) {

                    return apiResource.update(userItem,
                        successCallback, errorCallback);
                },
                remove: function(userItem, successCallback, errorCallback) {
                    return apiResource.remove({ userItemId: userItem.itemId },
                        successCallback, errorCallback);
                },
                getDefaultImage: function(userItem) {
                    if (userItem.isPrimaryManufacturer) {
                        return milwaukeeDefaultUrl;
                    }
                    return otherDefaultUrl;
                },
                bulkUpdate: function (request, successCallback, errorCallback) {
                    return bulkUpdateResource.save(
                        request,
                        successCallback, errorCallback);
                },
                getItemStatuses: function (success, error) {
                    return itemStatuses.query(null, success, error);
                },
                getCategoryUserItemTotals: function (searchFilters, callback) {
                    return categoryTotals.get(searchFilters, callback);
                },
                togglePendingLock: function (model, successCallback, errorCallback) {
                    return lockResource.update(model, successCallback, errorCallback);
                },
                updateSecurity: function (model, successCallback, errorCallback) {
                    return updateSecurityResource.save(model, 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';

    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.service('serviceRecords', ['$resource', 'urls', function ($resource, metUrls) {

        var deleteResource = $resource(metUrls('serviceRecordApi').concat('/:serviceRecordId'), { serviceRecordId: '@serviceRecordId' });

        var getTypesResource = $resource(metUrls('serviceRecordApi').concat('/types'), {}, {
            'query': {
                method: 'GET',
                isArray: true 
            }
        });

        var byUserItemResource = $resource(metUrls('serviceRecordApi').concat('/userItem/:userItemId'),
            {
                userItemId: '@userItemId'
            },
            {
                'update': { method: 'PUT' },
                'query': { method: 'GET', isArray: true }
            }
        );

        var byIdResource = $resource(metUrls('serviceRecordApi').concat('/:id/userItem/:userItemId'),
            {
                id: '@id',
                userItemId: '@userItemId'
            },
            {
                'update': { method: 'PUT' },
                'query': { method: 'GET', isArray: true }
            }
        );

        return {
            getAllByUserItemId: function (userItemId, success, error) {
                return byUserItemResource.query({ userItemId: userItemId }, success, error);
            },
            getTypes: function (success, error) {
                return getTypesResource.query(success, error);
            },
            update: function (serviceRecord, success, error) {
                return byIdResource.update(serviceRecord, success, error);
            },
            create: function (serviceRecord, success, error) {
                return byUserItemResource.save(serviceRecord, success, error);
            },
            remove: function (serviceRecordId, success, error) {
                return deleteResource.delete({ serviceRecordId: serviceRecordId}, success, error);
            }
        };
    }]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.service('items', ['$resource', 'urls', function ($resource, metUrls) {
        var resource = $resource(metUrls('toolSearch'),
        {},
        {
            'query': { method: 'GET', isArray: false }
        });
        return {
            searchItems: function (searchTerm, skip, take, success, error) {
                return resource.query(
                    { searchTerm: searchTerm, skip: skip, take: take },
                    success, error);
            }
        };
    }]);
}());

(function() {
    'use strict';

    var app = angular.module('oneKeyApp');

    app.directive('metFileUploader',
        [
            'Upload', '$log', 'notify', 'localize', 'urls', function($upload, $log, metNotify, metLocalize, metUrls) {
                return {
                    restrict: 'E',
                    scope: {
                        ngModel: '=',
                        ngModelList: '=',
                        metModelAlternates: '=',
                        metUploadUrl: '@',
                        metUploadAllowPdfs: '=',
                        metOnFileUploaded: '=',
                        metThumbDefault: '=',
                        metDefaultImage: '=',
                        metForceImage: '=',
                        metShowThumb: '@',
                        metImageDetailPosition: '@',
                        metDisableSave: '=?',
                        metDisabled: '=?',
                        metRemoveFile: '&?'
                    },
                    template:
                        '<div class="image-upload" data-ng-class="{\'image-upload-with-thumb\':showThumbnail}" data-ng-show="!metDisabled">' +
                            '<div data-ng-if="canUpload">' +
                            '<button data-ng-if="!metUploadAllowPdfs" class="btn btn-action-gray show-border" ngf-select="fileChanged($files)" accept="image/*" >{{buttonText.value}} ...</button> ' +
                            '<button data-ng-if="metUploadAllowPdfs && !fallback" class="btn btn-action-gray show-border" ngf-select="fileChanged($files)" accept="image/*, application/pdf" >{{buttonText.value}}</button> ' +
                            '<button data-ng-if="metUploadAllowPdfs && fallback" class="btn btn-action-gray show-border" ngf-select="fileChanged($files)">{{buttonText.value}}</button> ' +
                            '<met-image-thumb data-ng-if="showThumbnail" data-met-thumb-src="metModelAlternates.smallUrl" data-met-detail-src="metModelAlternates.mediumUrl" data-met-thumb-default="metThumbDefault" data-met-image-detail-position="{{metImageDetailPosition}}" ></met-image-thumb>' +
                            '<button data-ng-if="showRemoveButton()" data-ng-click="removeFile()" class="btn btn-action-gray show-border">{{ removeLink.value }}' +
                            '<div class="loading" data-ng-show="uploadingImage"><i class="fa fa-spinner fa-spin"></i></div>' +
                            '</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>' +
                            '<p class="small" ng-bind-html="installFlashToUpload.value"></p>' +
                            '</div>' +
                            '</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.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.showRemoveButton = function() {
                            if (!scope.ngModel ||
                                scope.ngModel == metUrls('milwaukeeDefault') ||
                                scope.ngModel == metUrls('otherDefault')) {
                                return false;
                            }
                            return true;
                        }

                        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 oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metImageThumb', [
        '$compile', '$rootScope', 'urls',
        function ($compile, $rootScope, metUrls) {
            var popoverTemplate = '<div class="popover popover-image-detail" role="tooltip"><h3 class="popover-title"></h3><button type="button" class="close close-overhang"><i class="icon icon-cross-circle fa-lg"></i><span class="sr-only">Close</span></button><div class="popover-content"></div></div>';
            var imagePopoverContentTemplate = '<img data-ng-src="{{detailsSrc()}}" alt ="{{altText}}" class="receipt-detail"/>';
            var pdfPopoverContentTemplate = 'Pdf Attached';
         
            return {
                restrict: 'EA',
                replace: true,
                scope: {
                    metThumbSrc: '=',
                    metDetailSrc: '=',
                    metThumbDefault: '=',
                    altText: '@alt',
                    metImageDetailPosition: '@',
                    metThumbClass: '@'
                },
                template:
                    '<span>' +
                        '<img class="item-thumbnail {{metThumbClass}}" data-ng-if="!isPdf()" data-ng-class="{\'pointer\':showPointer()}" ' +
                        'data-ng-src="{{displaySrc()}}" alt ="{{altText}}" onerror="this.src=\'/Content/images/placeholder_other.png\'"/>' +
                    '<a href="{{metDetailSrc}}" target="_blank" data-ng-if="isPdf()"><img class="item-thumbnail item-thumbnail-pdf" ' +
                        'data-ng-src="{{pdfIcon}}" alt="{{altText}}"/></a></span>',
                link: function (scope, element, attrs) {
                    var position = scope.metImageDetailPosition || 'left';

                    scope.unspecifiedImageUrl = metUrls('otherDefault');

                    scope.pdfIcon = metUrls('pdfIcon');
                    scope.isPdf = function () {
                        return scope.metThumbSrc && scope.metThumbSrc.endsWith('.pdf');
                    };
                    //checks the path of the uploaded file and verifies if it is an image or not.
                    scope.IsImageUploaded = function () {
                        if (scope.detailsSrc() != scope.metThumbSrc)
                            return true;
                        else return false;
                    };
                    scope.displaySrc = function () {
                        return scope.metThumbSrc || scope.metThumbDefault || scope.unspecifiedImageUrl;
                    };
                    scope.detailsSrc = function() {
                        return scope.metDetailSrc || scope.metThumbDefault;
                    }
                    scope.showPointer = function () {
                        return !scope.isPdf(scope.metThumbSrc) &&
                            (scope.metThumbSrc || scope.hasDefault);
                    };
                    scope.hasDefault = scope.metThumbDefault &&
                        scope.metThumbDefault != scope.unspecifiedImageUrl;

                    var hasPopover = false;
                    scope.$watch('metThumbSrc', function (newValue, oldValue) {
                        if (newValue && !hasPopover) {
                            //an image was added to the item, but the item doesn't have a popover for it.
                            // this is a weird hack. sometimes the popover doesn't work the first time.
                            bindPopover();
                            destroyPopover();
                            bindPopover();
                        }
                        else if (!newValue && scope.hasDefault && !hasPopover) {
                            // this is a weird hack. sometimes the popover doesn't work the first time.
                            bindPopover();
                            destroyPopover();
                            bindPopover();
                        }
                        else if (!newValue && oldValue && !scope.hasDefault && hasPopover) {
                            //it used to have an image, but doesn't anymore...
                            // and it doesn't have a clickable "default" image (i.e. it is not a milwaukee tool)
                            // and it has a popover for displaying the detail image
                            destroyPopover();
                        }
                    });
                    scope.$on('metImageDetailOpened', function (e, name) {
                        if (name != scope.popoverId) {
                            jQuery214(element).popover('hide');
                        }
                    });
                    scope.$on('$destroy', function () {
                        if (angular.isDefined(scope.popoverId)) {
                            jQuery214('#' + scope.popoverId).remove();
                        }
                        destroyPopover();
                    });

                    var destroyPopover = function () {
                        jQuery214(element).popover('destroy');
                        hasPopover = false;
                    };
                    var bindPopover = function () {
                        var htmlTemplate = scope.isPdf() ? pdfPopoverContentTemplate : imagePopoverContentTemplate;
                        var innerContent = $compile(htmlTemplate)(scope);
                        var options = {
                            template: popoverTemplate,
                            content: innerContent,
                            placement: position,
                            html: true,
                            trigger: 'click',
                            container: '#onekey'
                        };
                            jQuery214(element).popover(options)
                                .on('shown.bs.popover', function (e) {
                                    scope.popoverId = jQuery214(element).attr('aria-describedby');
                                    $rootScope.$broadcast('metImageDetailOpened', scope.popoverId);
                                    jQuery214('#' + scope.popoverId + ' .close').bind('click', function () {
                                        jQuery214(element).popover('hide');
                                    });
                                    angular.element(document).click(function () {
                                        jQuery214('#' + scope.popoverId).remove();
                                    });
                                });
                            hasPopover = true;
                        
                    };
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    angular.module('oneKeyApp')
        .directive('alertFrequency', alertFrequency);

    alertFrequency.$inject = ['$timeout', 'dates', 'language', 'localize', 'notify', 'inventory', 'notifications', '$rootScope'];

    function alertFrequency($timeout, metDates, metLanguage, localize, metNotify, metInventory, metAlerts, $rootScope) {

        var directive = {
            link: link,
            replace: true,
            scope: {
                itemDetails: '=',
                item: '=',
                serviceDate: '=',
                frequency: '=',
                serviceDateAlert: '=?'
            },
            restrict: 'EA',
            templateUrl: '/OneKeyScripts/app/directives/inventory/grid/alertFrequency.html'
        };
        return directive;

        function link(scope) {
            init();
            var iconLink = $('#calendartarget');
            scope.workingModel = scope.itemDetails;
            scope.isOpen = true;
            scope.selectedFrequency = null;
            scope.messages = {
                save: localize('commands', 'save'),
                cancel: localize('commands', 'cancel'),
                edit: localize('commands', 'edit'),
                repeats: localize('commands', 'repeats'),
                recurringAlerts: localize('commands', 'recurringAlerts'),
                selectDate: localize('commands', 'selectDate')
            };

            scope.alertFrequencyOptions = [];

            localize('messages', 'never').promise.then(function (val) {
                scope.alertFrequencyOptions[0] = val;
            });
            
            localize('messages', 'monthly').promise.then(function (val) {
                scope.alertFrequencyOptions[1] = val;
            });
            
            localize('messages', 'quarterly').promise.then(function (val) {
                scope.alertFrequencyOptions[2] = val;
            });
            
            scope.monthly = localize('messages', 'semiAnnually').promise.then(function (val) {
                scope.alertFrequencyOptions[3] = val;
            });
            
            scope.monthly = localize('messages', 'annually').promise.then(function (val) {
               scope.alertFrequencyOptions[4] = val;
            });

            var originalDate = scope.itemDetails.serviceDate;
            var originalFrequency = scope.itemDetails.serviceAlertFrequency;
            var defaultOrToday = isNullOrUndefined(scope.serviceDate) ? moment().today : scope.serviceDate;
            var currentDate = moment().startOf('day');
            var minDate = currentDate.toISOString();

            // Doing this to tackle the issue where the UserItem already has a Service Reminder date in the past
            if (defaultOrToday <= minDate) {
                $('#serviceDatePicker').datetimepicker({
                    inline: true,
                    format: metDates.date(false),
                    showClear: true,
                    minDate: minDate
                }).show();
            }

            scope.picker = $('#serviceDatePicker').datetimepicker({
                inline: true,
                sideBySide: false,
                debug: false,
                keepOpen: false,
                locale: metLanguage.getLocale(),
                defaultDate: defaultOrToday,
                format: metDates.date(false),
                showClear: true,
                minDate: minDate
            });
            
            scope.showDatePicker = true;
            scope.showFrequencyPicker = false;
            scope.toggle = toggle;
            scope.submit = submit;
            
            if (isNullOrUndefined(scope.selected)) {
                scope.selected = 0;
            };

            function toggle(shouldClose) {

                if (scope.selectedFrequency === null) {
                    scope.selectedFrequency = scope.alertFrequencyOptions[scope.itemDetails.serviceAlertFrequency];
                }

                if (localStorage.getItem('alert')) {
                    scope.selectedFrequency = localStorage.getItem('alert');
                    localStorage.removeItem('alert');
                }
                if (isNullOrUndefined(shouldClose)) {
                    shouldClose = false;
                }
                if (shouldClose) {
                    scope.isOpen = true;
                    hideContainer();
                } else {
                    scope.showDatePicker = !scope.showDatePicker;
                    scope.showFrequencyPicker = !scope.showFrequencyPicker;
                }
            }

            function submit() {
                scope.isOpen = true;

                if (scope.selectedFrequency !== null) {
                    localStorage.setItem('alert', scope.selectedFrequency);
                }

                var serviceDate = scope.picker.data().date;
                scope.itemDetails.serviceAlertFrequency = scope.selectedFrequency !== null
                        ? scope.alertFrequencyOptions.indexOf(scope.selectedFrequency)
                        : scope.itemDetails.serviceAlertFrequency;

                scope.itemDetails.serviceDate = serviceDate.length > 0 ? moment(serviceDate, metDates.date(false)).format(metDates.api) : null;

                scope.itemDetails.manufacturerId = scope.itemDetails.manufacturer.manufacturerId;
                scope.itemDetails.categoryId = scope.itemDetails.category.categoryId;
                scope.itemDetails.locationId = scope.itemDetails.location.locationId;
                scope.itemDetails.placeId = scope.itemDetails.place.placeId;
                scope.itemDetails.divisionId = scope.itemDetails.division.divisionId;
                scope.itemDetails.personId = scope.itemDetails.person.personId;


                if (scope.itemDetails.hasServiceDateAlert) {
                    metAlerts.dismiss(scope.serviceDateAlert.id,
                        function (response) {
                            $rootScope.$broadcast('alert-deleted', response);
                        }
                    );
                }
                metInventory.update(scope.itemDetails,
                    function (data) {
                        scope.itemDetails = data;
                        var unacknowledgedAlerts = [];
                        if (scope.itemDetails.notifications.length > 0) {
                            unacknowledgedAlerts = $.grep(scope.itemDetails.notifications, function (notification) { return notification.acknowledgedOn === null; });
                        }
                        if (scope.item.alertCount !== unacknowledgedAlerts.length) {
                            $rootScope.$broadcast('update-notifications-count', {});
                            scope.item.alertCount = unacknowledgedAlerts.length;
                        }
                    }, function (error) {
                        scope.itemDetails.serviceDate = originalDate;
                        scope.itemDetails.serviceAlertFrequency = originalFrequency;
                        metNotify.error(error.data.message);
                        $timeout(function () {
                            if (scope.itemDetails.serviceAlertFrequency === 0 || isNullOrUndefined(scope.itemDetails.serviceAlertFrequency)) {
                                $('#serviceDateAndFrequency').css('display', 'none');
                            }

                        }, 200);
                       
                        console.log(error.data.message);
                    }
                );
                hideContainer();
            }

            iconLink.click(function () {
                scope.isOpen = !scope.isOpen;
                return scope.isOpen ? hideContainer() : showContainer();
            });

            function showContainer() {
                $('#serviceAlertContainer').css('display', 'block');
            }

            function hideContainer() {
                $('#serviceAlertContainer').css('display', 'none');
            }

            function isNullOrUndefined(obj) {
                return obj === null || obj === undefined;
            };

            function init() {
                hideContainer();
            }
        }
    };

})();
(function (module) {
    'use strict';

    var metAddEdit = function ($compile, urls, localize, dates, serviceRecords, metNotify, $modal, modalOptionsService, $filter, metServiceRecordUploads) {

        return {
            restrict: 'E',
            replace: true,
            templateUrl: '/OneKeyScripts/app/directives/inventory/grid/metAddEdit.directive.html',
            scope: {
                item: '=',
                selectedRecord: '=?',
                serviceRecordItems: '=',
                emptyServiceRecords: '=?',
                hasUploads: '=',
                reloadRecords: '&'
            },
            link: function (scope, element, attrs) {
                scope.messages = {
                    date: localize('fieldNames', 'date'),
                    cost: localize('fieldNames', 'cost'),
                    save: localize('fieldNames', 'save'),
                    serviceRecord: localize('fieldNames', 'serviceRecord'),
                    servicedBy: localize('fieldNames', 'servicedBy'),
                    notes: localize('fieldNames', 'notes'),
                    addRecord: localize('commands', 'addRecord'),
                    edit: localize('commands', 'edit'),
                    add: localize('commands', 'add'),
                    view: localize('commands', 'view'),
                    serviceDate: localize('fieldNames', 'serviceDateLabel'),
                    serviceType: localize('fieldNames', 'serviceType'),
                    cancel: localize('commands', 'cancel'),
                    required: localize('validation', 'requiredError'),
                    addRecordConversational: localize('commands', 'addRecordConversational'),
                    editView: localize('commands', 'edit_View'),
                    uploadedItems: localize('fieldNames', 'uploadedItems'),
                    delete: localize('commands', 'delete'),
                    deleteConfirm: localize('messages', 'deleteUploadConfirm'),
                    attachFiles: localize('fieldNames', 'attachFiles'),
                    attachText: localize('messages', 'attachText'),
                    uploads: localize('fieldNames', 'uploads'),
                    serviceDateRequired: localize('messages', 'serviceDateRequired')
                };
                scope.epochStart = moment('1970-01-01T00:00:00.000').format();
                scope.serviceRecord = {};
                scope.datePickerOptions = dates.getDatePickerOptions('bottom');
                scope.statuses = scope.item.statuses;
                scope.serviceTypes = [];
                scope.selectedType = {};
                scope.getContainer = getContainer;
                scope.hideAddDialog = hideAddDialog;
                scope.isEdit = false;
                scope.dateFormat = dates.date(true);
                scope.serviceUploadRecordChanged = false;

                if (scope.selectedRecord !== undefined) {
                    scope.serviceRecord = scope.selectedRecord;
                    scope.serviceRecord.date = $filter('date')(scope.serviceRecord.date, dates.date(true));
                    scope.isEdit = true;
                }
                else {
                    var today = moment().format();
                    scope.serviceRecord.date = $filter('date')(today, dates.date(true));
                    scope.serviceRecord.cost = 0;
                }

                scope.save = function () {
                    var serviceDate = scope.isEdit ? document.querySelector('#serviceDateInputEdit').value : document.querySelector('#serviceDateInputAdd').value;

                    if (serviceDate.length <= 0) {
                        metNotify.error(scope.messages.serviceDateRequired.value);
                        return;
                    }
                    scope.serviceRecord.userItemId = scope.item.id;
                    scope.serviceRecord.typeId = scope.selectedType.id;
                    scope.serviceRecord.notes = document.querySelector('#serviceRecordNoteText').value;

                    if (!scope.isEdit) {
                        scope.serviceRecord.date = serviceDate.length > 0 ? moment(serviceDate, dates.date(false)).format(dates.api) : moment().format(dates.getDatePickerOptions().format);
                        if (scope.serviceRecord.date < scope.epochStart) {
                            scope.serviceRecord.date = scope.epochStart;
                        }
                        serviceRecords.create(scope.serviceRecord,
                            function (data) {
                                scope.refreshServiceRecords(false);
                            },
                            function (data) {
                                openModal();
                            });
                    } else {
                        // Needed in the case someone uploads something before saving their record.
                        if (scope.selectedRecord === undefined) {
                            scope.selectedRecord = scope.serviceRecord;
                        }

                        scope.selectedRecord.date = serviceDate.length > 0 ? moment(serviceDate, dates.date(false)).format(dates.api) : moment().format(dates.getDatePickerOptions().format);
                        if (scope.selectedRecord.date < scope.epochStart) {
                            scope.selectedRecord.date = scope.epochStart;
                        }
                        serviceRecords.update(scope.selectedRecord,
                            function () {
                                scope.refreshServiceRecords(false);
                            },
                            function () {
                                openModal();
                            });
                    }

                };

                scope.cancel = function () {
                    scope.refreshServiceRecords(false);
                }

                serviceRecords.getTypes(function (data) {
                    scope.serviceTypes = data;
                    scope.selectedType = getSelectedDataType(data);
                }, function () {
                    openModal();
                });

                scope.delete = function (id) {
                    metServiceRecordUploads.remove(id, function () {
                        scope.refreshServiceRecords(true);
                    });
                };

                scope.update = function (userItemResource) {
                    scope.serviceUploadRecordChanged = true;
                    userItemResource.title = userItemResource.uploadTitle;
                    metServiceRecordUploads.update(userItemResource, function () {
                        scope.refreshServiceRecords();
                    });
                };

                function openModal() {
                    $modal.open(modalOptionsService.generalErrorModalOptions);
                }

                function getSelectedDataType(data) {
                    if (scope.selectedRecord) {
                        var selectedDataType = data.filter(function (type) {
                            return type.id === scope.selectedRecord.typeId;
                        });
                        return selectedDataType[0];
                    }
                    return data[3];
                }
                scope.isNumberKey = function ($event) {
                    if (isNaN(String.fromCharCode($event.keyCode)) && $event.which !== 8 && $event.which !== 46) {
                        $event.preventDefault();
                    }
                }

                scope.refreshServiceRecords = function (isEdit) {
                    serviceRecords.getAllByUserItemId(scope.item.id,
                        function (response) {
                            scope.serviceRecordItems = response;
                            if (scope.isEdit) {
                                scope.serviceRecord.serviceRecordUploads = $.grep(scope.serviceRecordItems,
                                        function(record) { return record.id === scope.serviceRecord.id })[0].serviceRecordUploads;
                                scope.hasUploads = scope.serviceRecord.serviceRecordUploads.length > 0;
                                scope.serviceRecord.date = $filter('date')(scope.serviceRecord.date, dates.date(true));
                                scope.serviceRecord.cost =
                                    scope.serviceRecord.cost === null ? 0 : scope.serviceRecord.cost;

                                for (var z = 0; z < scope.serviceRecord.serviceRecordUploads.length; z++) {
                                    scope.serviceRecord.serviceRecordUploads[z].createdOnLocal = dates.convertUtcToLocal(scope.serviceRecord.serviceRecordUploads[z].createdOn, scope.dateFormat);
                                }
                            }

                            for (var i = 0; i < scope.serviceRecordItems.length; i++) {
                                scope.serviceRecordItems[i].localDate = $filter('date')(scope.serviceRecordItems[i].date, dates.date(true));
                                scope.serviceRecordItems[i].cost =
                                    scope.serviceRecordItems[i].cost === null ? 0 : scope.serviceRecordItems[i].cost;
                            }

                            if (!isEdit && isEdit !== undefined) {
                                var container = getContainer();
                                hideAddDialog(container);
                            }
                            scope.emptyServiceRecords = scope.serviceRecordItems.length <= 0;

                            if (scope.serviceUploadRecordChanged) {
                                scope.selectedRecord = scope.serviceRecord;
                            }
                        },
                        function () {
                        });
                };

                function getContainer() {
                    return element.parents('#itemDetails');
                }

                function hideAddDialog(container) {
                    container.children().css('display', 'block');
                    $('#oneKeyAddEditContainer').remove();
                }

                function showAddDialog(container) {
                    container.children().css('display', 'none');
                    $('#oneKeyAddEditContainer').css('display', 'block');
                }
            }
        }
    };

    metAddEdit.$inject = ['$compile', 'urls', 'localize', 'dates', 'serviceRecords', 'notify', '$modal', 'modalOptionsService', '$filter', 'serviceRecordUploads'];
    module.directive('metAddEdit', metAddEdit);

}(angular.module('oneKeyApp')));
(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metGrid', [
        '$filter', 'urls', 'localize', 'userItems', 'metLocalStorage', 'inventoryFilters', 'inventoryGridConfig', 'notify', '$stateParams', 'notifications',
        function ($filter, metUrls, metLocalize, metUserItems, metLocalStorage, metInventoryFilters, metInventoryGrid, metNotify, $stateParams, metNotifications) {
           return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryGridHtml'),
                scope: {
                    loading: '=',
                    refreshGrid: '=',
                    userItemId: '=',
                    tickUrl: '@'
               },
               link: function (scope, element, attrs) {
                    scope.refreshGrid = refreshGrid;

                    if ($stateParams.success !== null && $stateParams.success !== undefined) {
                        scope.refreshGrid(false);
                    }
                    scope.noInventory = scope.loadedGroups && scope.loadedGroups[0].items.length === 0;
                    scope.loadedGroups = metInventoryGrid.loadedGroups;
                   scope.messages = {
                       howToActiviateToolSecurity: metLocalize('messages', 'howToActiviateToolSecurity'),
                       addItemButton: metLocalize('commands', 'addItemButton'),
                       noInventory: metLocalize('messages', 'noInventory'),
                       emptyInventoryText: metLocalize('messages', 'emptyInventoryText'),
                       noResults: metLocalize('messages', 'noResults'),
                       noResultsForFilters: metLocalize('messages', 'noResultsForFilters'),
                       clearFilters: metLocalize('commands', 'clearFilters')
                   };

                    scope.collapseAllItems = function () {
                        _.forEach(scope.loadedGroups, function (group, index) {
                            _.forEach(group.items, function (item, index) {
                                item.isExpanded = false;
                            });
                        });
                    }

                    scope.selectGroupItems = function (groupId) {
                        metInventoryGrid.allItemsSelected = false;
                        var selectedGroup = $filter('filter')(scope.loadedGroups, { id: groupId })[0];
                        if (selectedGroup) {
                            _.forEach(selectedGroup.items, function (item, index) {
                                item.selected = selectedGroup.selected;
                            });
                        }
                        metInventoryGrid.updateSelectedFields();
                    }

                    scope.hasFilters = metInventoryFilters.hasFilters();
                    scope.hasSearchTerm = metInventoryFilters.searchTerm.length > 0;

                    scope.clearFilters = function () {
                        metInventoryFilters.removeAllFilters();
                        metInventoryFilters.searchTerm = '';
                        scope.refreshGrid();
                    }

                    function refreshGrid (isPaging) {
                        scope.loading = true;
                        if (!isPaging) {
                            metInventoryGrid.pageIndex = 0;
                            metInventoryFilters.updateFilterResults();
                            metInventoryGrid.allItemsSelected = false;
                            metInventoryGrid.selectAll();
                        }
                        scope.hasFilters = metInventoryFilters.hasFilters();
                        scope.hasSearchTerm = metInventoryFilters.searchTerm.length > 0;
                        var oneKey = localStorage.getItem("oneKeyOnly");
                        var tick = localStorage.getItem("tickOnly");

                        var filters = metInventoryFilters.searchRequest;
                        if (oneKey) { filters.oneKey = oneKey; }
                        if (tick) { filters.tick = tick; }
                        filters.sortField = metInventoryGrid.gridSort.field;
                        filters.sortDescending = metInventoryGrid.gridSort.isDescending;
                        filters.take = metInventoryGrid.resultsPerPage;
                        filters.groupBy = metInventoryGrid.groupBy;
                        filters.skip = metInventoryGrid.getSkipTotal();

                        if (scope.userItemId > 0) {
                            filters.itemId = scope.userItemId;
                        }

                        metUserItems.search(filters, function (response) {
                            metInventoryFilters.updateAvailableFilters(response.availableFilters, isPaging);
                            metInventoryGrid.gridUpdated(response);
                            scope.loadedGroups = metInventoryGrid.loadedGroups;
                            _.forEach(scope.loadedGroups,
                                function(group) {
                                    _.forEach(group.items,
                                        function(item) {
                                            item.alertCount = $filter('filter')(scope.notifications,
                                                { userItemId: item.id, acknowledgedOn: null }).length;
                                        });
                                });
                            scope.loading = false;
                            // Sending custom dimension for inventory size to google analytics.
                            var tracker = ga.getAll()[0];
                            console.log('tracker before set');
                            var gaInventoryBucket = "0";
                            if (metInventoryGrid.totalResults > 0 && metInventoryGrid.totalResults <= 9) {
                                gaInventoryBucket = "1-9";
                            } else if (metInventoryGrid.totalResults >= 10 && metInventoryGrid.totalResults <= 99) {
                                gaInventoryBucket = "10-99";
                            } else if (metInventoryGrid.totalResults >= 100 && metInventoryGrid.totalResults <= 999) {
                                gaInventoryBucket = "100-999";
                            } else if (metInventoryGrid.totalResults >= 1000) {
                                gaInventoryBucket = "1000+";
                            } else {
                                gaInventoryBucket = "0";
                            }
                            tracker.set('dimension1', gaInventoryBucket);
                            console.log(tracker.get('dimension1'));
                            ga('send', 'event', 'inventorySize', 'loadedInventory');
                            
                            scope.noInventory = metInventoryGrid.totalResults === 0;
                            if (scope.userItemId > 0) {
                                _.forEach(scope.loadedGroups, function (group) {
                                    _.forEach(group.items, function (item) {
                                        item.isExpanded = true;
                                    });
                                });
                            }
                        });

                        var quickFilters = document.getElementsByClassName('met-filter-chip');

                        if (quickFilters.length > 0) {
                            _.forEach(quickFilters, function (quickFilter) {
                                var disp = quickFilter.style.display;
                                quickFilter.style.display = 'none';
                                setTimeout(function () {
                                    quickFilter.removeAttribute('style');
                                }, 15);
                            })
                        }
                    }

                    scope.notifications = [];

                    function init() {
                        metNotifications.getAll(function(response) {
                            scope.notifications = response.items;
                        }, function(error) {
                            scope.notifications = [];
                        });

                        scope.refreshGrid();

                        if (localStorage.getItem('displayHowToActiviateToolSecurity')) {
                            localStorage.removeItem('displayHowToActiviateToolSecurity');

                            setTimeout(function () {
                                // firing off a bit later to give the page a bit more time to load.
                                metNotify.success(scope.messages.howToActiviateToolSecurity.value);
                            }, 500);
                        }
                    }
                    init();
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metGridConfig', [
        '$window', 'urls', 'localize', 'inventoryGridConfig', 'metLocalStorage', 'host',
        function ($window, metUrls, metLocalize, metInventoryGrid, metLocalStorage, host) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryGridConfigHtml'),
                scope: {
                    updateResults: '&'
                },
                link: function (scope, element, attrs) {
                    scope.messages = {
                        resultsPerPage: metLocalize('messages', 'resultsPerPage'),
                        addRemoveGridColumns: metLocalize('messages', 'addRemoveGridColumns'),
                        gridGrouping: metLocalize('messages', 'gridGrouping'),
                        selectEightOptions: metLocalize('commands', 'selectEightOptions'),
                        configureColumns: metLocalize('commands', 'configureColumns')
                    }
                    scope.host = host;
                    scope.resultsPerPage = metInventoryGrid.resultsPerPage;

                    var userAgent = $window.navigator.userAgent;

                    var browsers = { chrome: /chrome/i, safari: /safari/i, firefox: /firefox/i };
                    var notIe = false;
                    for (var key in browsers) {
                        if (browsers.hasOwnProperty(key)) {
                            if (browsers[key].test(userAgent)) {
                                notIe = true;
                            }
                        }
                    };
                    scope.resultsPerPageOptions = notIe === false ? [10, 25, 50] : [10, 25, 50, 100, 200];

                    scope.changeResultsPerPage = function (resultOption) {
                        scope.resultsPerPage = resultOption;
                        metInventoryGrid.setResultsPerPage(resultOption);
                        scope.updateResults();
                    }
;
                    if (localStorage.getItem('column')) {
                        scope.defaultChecked = localStorage.getItem('column');
                    }
                    else {
                        scope.defaultChecked = 7;
                    }
                    scope.limitColumns = 8;

                    scope.columns = metInventoryGrid.headerValues;
                    scope.changeColumns = function (column, isVisible, $event) {
                        if (localStorage.getItem('column')) {
                            scope.defaultChecked = localStorage.getItem('column');
                        }
                        column.isVisible = isVisible;
                        if (column.isVisible) {
                            scope.defaultChecked++;
                        }
                        else {
                            scope.defaultChecked--;
                        }
                        localStorage.setItem('column', scope.defaultChecked);
                        metLocalStorage.setColumnInfo(column.columnName, { visible: isVisible });
                        $event.stopPropagation();
                    }

                    scope.propagation = function ($event) {
                        $event.stopPropagation();
                    }

                    scope.groupByOptions = [
                        { id: 0, label: metLocalize('messages', 'noGridGrouping'), },
                        { id: 1, label: metLocalize('fieldNames', 'categoryId') },
                        { id: 2, label: metLocalize('fieldNames', 'placeId') },
                        { id: 3, label: metLocalize('fieldNames', 'manufacturerId') },
                        { id: 4, label: metLocalize('fieldNames', 'itemStatus') },
                        { id: 5, label: metLocalize('fieldNames', 'personId') },
                        { id: 6, label: metLocalize('fieldNames', 'divisionId') },
                    ];

                    scope.selectedGroupBy = scope.groupByOptions[0];
                    scope.changeGroupBy = function (groupBy) {
                        scope.selectedGroupBy = groupBy;
                        metInventoryGrid.groupBy = groupBy.id;
                        scope.updateResults();
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metGridHeaders', [
        'urls', 'localize', 'metLocalStorage', 'inventoryGridConfig',
        function (metUrls, metLocalize, metLocalStorage, metInventoryGrid) {
            return {
                restrict: 'A',
                replace: true,
                templateUrl: metUrls('inventoryGridHeadersHtml'),
                scope: {
                    refreshGrid: '&'
                },
                link: function (scope, element, attrs) {
                    scope.gridConfig = metInventoryGrid;
                    scope.headerValues = metInventoryGrid.headerValues;

                    scope.setSortColumn = function (header) {
                        _.forEach(scope.headerValues, function (value, index) {
                            value.isSorted = false;
                            value.sortDescending = false;
                        });

                        if (metInventoryGrid.gridSort.field !== header.columnName) {
                            metInventoryGrid.gridSort.field = header.columnName;
                            metInventoryGrid.gridSort.isDescending = false;
                        } else {
                            metInventoryGrid.gridSort.isDescending = !metInventoryGrid.gridSort.isDescending;
                        }

                        metLocalStorage.setGridSort(metInventoryGrid.gridSort);
                        scope.refreshGrid();
                        header.isSorted = true;
                        header.sortDescending = metInventoryGrid.gridSort.isDescending;

                        setTimeout(function () {
                            var ua = window.navigator.userAgent;

                            var msie = ua.indexOf("MSIE"); // older versions of IE
                            var trident = ua.indexOf('Trident/'); // IE 11
                            var edge = ua.indexOf('Edge/'); // Microsoft Edge

                            if (trident > -1 || edge > -1 || msie > -1) // If Internet Explorer or edge
                            {
                                var tableOffset = $("#inventoryTable").offset().top;
                                var $header = $("#inventoryTable > thead").clone();
                                var $fixedHeader = $("#header-fixed").append($header);
                                $("#header-fixed th").each(function (index) {
                                    var index2 = index;
                                    $(this).width(function (index2) {
                                        return $("#inventoryTable th").eq(index).width();
                                    });
                                });
                                $("#header-fixed").width($("#inventoryTable").width());
                                $(window).bind("scroll", function () {
                                    var offset = $(this).scrollTop();

                                    if (offset >= tableOffset && $fixedHeader.is(":hidden")) {
                                        $fixedHeader.show();
                                    }
                                    else if (offset < tableOffset) {
                                        $fixedHeader.hide();
                                    }
                                });
                            }
                        }, 3000);
                    }

                    scope.selectAll = function () {
                        metInventoryGrid.selectAll();
                    }
                }
            };
        }
    ]);
}());
(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metGridItem', [
        '$window', 'urls', 'localize', 'metLocalStorage', 'dates', 'inventoryGridConfig', 'inventory',
        function ($window, metUrls, metLocalize, metLocalStorage, metDates, metGridConfig, metInventory) {
            return {
                restrict: 'A',
                replace: true,
                templateUrl: metUrls('inventoryGridItemHtml'),
                scope: {
                    item: '=metItem',
                    group: '=metGroup',
                    collapseAll: '&metCollapseAll'
                },
                link: function (scope, element, attrs) {
                    scope.dateTimeFormat = metDates.shortDateTime(true);
                    scope.dateFormat = metDates.date(true);
                    scope.messages = {
                        oneKeyItem: metLocalize('messages', 'oneKeyItem')
                    }

                    scope.itemSelected = function ($event) {
                        $event.stopPropagation();
                        metGridConfig.allItemsSelected = false;
                        scope.group.selected = false;
                        metGridConfig.updateSelectedFields();
                    }


                    var isFrench = function () {
                    	var current = $window.location.pathname;
                    	return current.indexOf('/fr') > -1;
                    };
                    
                    scope.showColumn = function (columnName) {
                        return metGridConfig.columnIsVisible(columnName);
                    }

                    scope.expandGridItem = function () {
                        var isExpanded = !scope.item.isExpanded;
                        scope.collapseAll();
                        scope.item.isExpanded = isExpanded;
                    }

					var detailsUrl = metUrls('inventoryDetails').concat('/' + scope.item.id);
				    scope.goToDetails = function () {
						$window.location.href = detailsUrl;
                    }

                    scope.lastSeenDate = metDates.convertUtcToLocal(scope.item.lastSeen);
                    scope.hasMessages = false;
                    scope.coinCellMessage;
                    scope.serviceMessage;
                    scope.toolLockedMessage;
                    var init = function() {
                        scope.hasMessages = scope.item.coinCellAlert > 0 || scope.item.serviceAlert > 0 || scope.item.isLocked == true || scope.item.statusId > 0;

                        if (scope.item.coinCellAlert == 2) {
                            scope.toolLockedMessage = metLocalize('messages', 'toolLocked');
                        }
                        
                        if (scope.item.location == null) {
                        	scope.item.location = metLocalize('titles', 'unassigned').value;
                        }
                        if (scope.item.person == null) {
                        	scope.item.person = metLocalize('titles', 'unassigned').value;
                        }
                        if (scope.item.trade == null) {
                        	scope.item.trade = metLocalize('titles', 'unassigned').value;
                        }

                        switch (scope.item.coinCellAlert) {
                            case 1:
                                scope.coinCellMessage = metLocalize('messages', 'coinCellWarning').value;
                                break;
                            case 2:
                                scope.coinCellMessage = metLocalize('messages', 'coinCellAlert').value;
                                break;
                        }

                        switch (scope.item.serviceAlert) {
                            case 1:
                                scope.serviceMessage = metLocalize('messages', 'serviceWarning').value;
                                break;
                            case 2:
                                scope.serviceMessage = metLocalize('messages', 'serviceAlert').value;
                                break;
                        }
                    }

                    init();
                }
            };
        }
    ]);
}());
(function () {
    "use strict";
    var oneKeyApp = angular.module('oneKeyApp');
    oneKeyApp.directive('metGridItemDetails', [
        '$state', '$window', 'urls', 'localize', 'items', 'dates', 'inventory', 'userItems', 'manufacturers', 'locations', 'people', 'trades', 'itemFieldFactory', 'addFormModel', '$filter', '$modal', 'modalOptionsService', 'notifications', 'categories',
        function ($state, $window, metUrls, metLocalize, metItems, metDates, metInventory, metUserItems, metManufacturers, metLocations, metPeople, metTrades, metItemFields, addFormModel, filter, $modal, modalOptionsService, metAlerts, metCategories) {

            return {
                restrict: 'A',
                replace: true,
                templateUrl: metUrls('inventoryGridItemDetailsHtml'),
                scope: {
                    item: '=metItem',
                    locations: '&',
                    people: '&',
                    trades: '&',
                    statuses: '&',
                    tickUrl: '@'
                },
                link: function (scope, element, attrs) {
                    scope.locations = [];
                    scope.trades = [];
                    scope.people = [];
                    scope.selectedPlace = {};
                    scope.selectedPerson = {};
                    scope.selectedDivision = {};
                    scope.states = $state.get();
                    scope.isValidModelNumber = false;
                    scope.datePickerOptions = metDates.getDatePickerOptions('bottom');
                    scope.detailEditView = false;
                    scope.purchaseInfoView = true;
                    scope.tabSelectedIndex = {index: 0};
                    scope.notesView = false;
                    scope.uploadsView = false;
                    scope.itemFields = metItemFields;
                    scope.serviceDatePicker = '';
                    scope.timeFromEntry = '';
                    scope.loading = true;
                    scope.selectedStatus = {};
                    scope.lastSeenText = "";
                    scope.showOverviewPanel = false;
                    scope.address = "";
                    scope.imageUploadUrl = metUrls('imagesUserItemsApi');
                    scope.filter = filter;
                    scope.serviceDateByRegion = null;
                    scope.notificationList = [];
                    scope.itemDetails = [];
                    scope.itemDetails.hasServiceDateAlert = false;
                    scope.isLatestScanned = false;
                    scope.setSelectedStatus = setSelectedStatus;
                    scope.messages = {
                        lastLocation: metLocalize('commands', 'lastLocation'),
                        viewDetails: metLocalize('commands', 'viewDetails'),
                        noNotifications: metLocalize('commands', 'noNotifications'),
                        toolNumber: metLocalize('fieldNames', 'inventoryToolNumber'),
                        status: metLocalize('fieldNames', 'itemStatus'),
                        itemDetails: metLocalize('fieldNames', 'itemDetails'),
                        person: metLocalize('fieldNames', 'personId'),
                        location: metLocalize('fieldNames', 'location'),
                        place: metLocalize('fieldNames', 'placeId'),
                        division: metLocalize('fieldNames', 'divisionId'),
                        serviceDate: metLocalize('fieldNames', 'serviceDate'),
                        itemValue: metLocalize('fieldNames', 'itemValue'),
                        coinCellLeft: metLocalize('fieldNames', 'coinCellLeft'),
                        itemWasAdded: metLocalize('messages', 'itemWasAdded'),
                        lastSeen: metLocalize('fieldNames', 'lastSeen'),
                        lastScanned: metLocalize('messages', 'lastScanned'),
                        year: metLocalize('messages', 'year'),
                        years: metLocalize('messages', 'years'),
                        month: metLocalize('messages', 'month'),
                        months: metLocalize('messages', 'months'),
                        day: metLocalize('messages', 'day'),
                        days: metLocalize('messages', 'days'),
                        toolHistory: metLocalize('fieldNames', 'toolHistory'),
                        noAddressFound: metLocalize('messages', 'noAddressFound'),
                        itemOverview: metLocalize('fieldNames', 'itemOverview'),
                        serviceRecord: metLocalize('fieldNames', 'serviceRecord'),
                        purchaseInformation: metLocalize('fieldNames', 'purchaseInformation'),
                        purchaseInfo: metLocalize('fieldNames', 'purchaseInfo'),
                        addPurchaseInfo: metLocalize('messages', 'addPurchaseInfo'),
                        notes: metLocalize('fieldNames', 'notes'),
                        alerts: metLocalize('titles', 'alerts'),
                        edit: metLocalize('fieldNames', 'edit'),
                        brand: metLocalize('fieldNames', 'manufacturer'),
                        modelNumber: metLocalize('fieldNames', 'modelNumber'),
                        serialNumber: metLocalize('fieldNames', 'serialNumber'),
                        description: metLocalize('fieldNames', 'itemDescription'),
                        save: metLocalize('commands', 'save'),
                        cancel: metLocalize('commands', 'cancel'),
                        toolPhoto: metLocalize('fieldNames', 'toolPhoto'),
                        category: metLocalize('fieldNames', 'categoryId'),
                        objectiveData: metLocalize('fieldNames', 'objectiveData'),
                        track: metLocalize('messages', 'track'),
                        trackMessage: metLocalize('messages', 'trackMessage'),
                        learnMore: metLocalize('commands', 'learnMore'),
                        seenByOneKey: metLocalize('messages', 'seenByOneKey'),
                        editItem: metLocalize('messages', 'editItem'),
                        oneKey: metLocalize('titles', 'oneKey'),
                        lastSync: metLocalize('fieldNames', 'lastSyncedOn'),
                        resources: metLocalize('fieldNames', 'resources'),
                        duplicate: metLocalize('messages', 'duplicate'),
                        uploads: metLocalize('fieldNames', 'uploads'),
                        itemSn: metLocalize('fieldNames', 'itemSn'),
                        tickSn: metLocalize('fieldNames', 'tickSn'),
                        manufacturer: metLocalize('fieldNames', 'manufacturerId'),
                        add: metLocalize('commands', 'add'),
                        searchOrAdd: metLocalize('commands', 'searchOrAdd'),
                        addPersonOption: metLocalize('commands', 'addPersonOption'),
                        addLocationOption: metLocalize('commands', 'addLocationOption'),
                        addDivisionOption: metLocalize('commands', 'addDivisionOption'),
                        addCategoryOption: metLocalize('commands', 'addCategoryOption'),
                        addManufacturerOption: metLocalize('commands', 'addManufacturerOption'),
                        noResultsFound: metLocalize('messages', 'noResultsFound'),
                        pendingLock: metLocalize('messages', 'pendingLock'),
                        itemLocked: metLocalize('messages', 'itemLocked'),
                        addPlaceOption: metLocalize('commands', 'addPlaceOption'),
                        outsideGeofence: metLocalize('messages', 'outsideGeofence'),
                        barcode: metLocalize('messages', 'barcodeDisplay'),
                        requiredError: metLocalize('validation', 'requiredError')
                    };

                    scope.seenOutsideGeofence = false;
                    scope.firstLetterStatusGroupFn = function (item) {
                        return item.statusName.charAt(0).toUpperCase();
                    };
                    scope.firstLetterDivisionGroupFn = function (item) {
                        return item.divisionName.charAt(0).toUpperCase();
                    };
                    scope.firstLetterPersonGroupFn = function (item) {
                        return item.personName.charAt(0).toUpperCase();
                    };
                    scope.firstLetterPlaceGroupFn = function (item) {
                        return item.placeName.charAt(0).toUpperCase();
                    };
                    scope.firstLetterCategoryGroupFn = function (item) {
                        return item.categoryName.charAt(0).toUpperCase();
                    };
                    scope.firstLetterManufacturerGroupFn = function (item) {
                        return item.manufacturerName.charAt(0).toUpperCase();
                    };
                    scope.orderFilterFn = function (groups) {
                        return groups;
                    };

                    scope.duplicateItem = function (item) {
                        addFormModel.manufacturer = item.manufacturer;
                        addFormModel.modelNumber = item.modelNumber;
                        addFormModel.description = item.itemDescription;
                        addFormModel.category = item.category;
                        addFormModel.division = item.division;
                        addFormModel.imageAlternates = item.imageAlternates;
                        addFormModel.value = item.price;
                        $state.go('add-new', {fromState: 'existing', productId: item.productId});
                    };

                    scope.setEdit = function (isEdit, isCancel) {
                        scope.detailEditView = isEdit;
                        if (isCancel) {
                            init(isCancel);
                            return;
                        }
                        $('#serialNumberEditContainer').removeClass('md-input-invalid');
                    };

                    scope.setResourcesView = function (isPurchase, isNotes, isUploadsView) {
                        scope.purchaseInfoView = isPurchase;
                        scope.notesView = isNotes;
                        scope.uploadsView = isUploadsView;
                    };

                    scope.saveDetails = function () {
                        scope.saveForm();
                    };

                    scope.onDropDownOpenClose = function(isOpen, dropDown) {
                        var dropDownNames = ['uisStatus', 'uisPlaces', 'uisPersons', 'uisDivisions'];
                        var inputId = dropDown.$select.searchInput[0].id;
                        var elLabel = document.querySelector('#'.concat(inputId).concat('Label'));
                        var elOuterDiv = document.querySelector('#'.concat(inputId).concat('Select'));
                        var nextInputIdIndex = dropDownNames.indexOf(inputId) + 1;

                        var nextSelect = function(index) {
                            return dropDownNames[index]
                                ? document.querySelector("[input-id='" + dropDownNames[index] + "']")
                                : null;
                        }(nextInputIdIndex);
                        
                        if (isOpen) {
                            elLabel.style.visibility = 'hidden';
                            elOuterDiv.style.display = 'block';
                            if (nextSelect) {
                                nextSelect.style.visibility = 'hidden';
                            }
                        }
                        else {
                            elLabel.style.visibility = 'visible';
                            elOuterDiv.style.display = 'none';
                            if (nextSelect) {
                                nextSelect.style.visibility = 'visible';
                            }
                        }
                    }

                    scope.triggerAddNewPlace = function (place) {
                        createPlaceModal(place);
                    }

                    scope.triggerAddNewPerson = function (person) {
                        createPersonModal(person);
                    }

                    scope.triggerAddNewDivision = function (division) {
                        createDivisionModal(division);
                    }

                    scope.loadItems = function () {
                        metLocations.getAll({includeUnspecified: true, forAssignment: true}, function (data) {
                            scope.locations = data.items;
                        });

                        metTrades.getAll({includeUnspecified: true}, function (data) {
                            scope.trades = data.items;
                        });

                        metPeople.getAll({includeUnspecified: true}, function (data) {
                            scope.people = data.items;
                        });

                        metManufacturers.getAll({includeUnspecified: true}, function (data) {
                            scope.manufacturers = data.items;
                            var newManufacturer = {
                                manufacturerName: scope.messages.addManufacturerOption.value,
                                manufacturerId: -2
                            };
                            scope.manufacturers.unshift(newManufacturer);
                        });

                        metItemFields.loadStatuses();
                        getCategories();

                        scope.statuses = metItemFields.statuses;

                        metAlerts.getItemNotifications(scope.item.id,
                            function (data) {
                                scope.notificationList = data.items;
                                var result = $.grep(scope.notificationList, function (alert) { return alert.notificationType === 'ServiceDateAlert'; });
                                if (result.length > 0) {
                                    scope.itemDetails.hasServiceDateAlert = true;
                                    scope.serviceDateAlert = result[0];
                                }
                            });
                    };

                    scope.getDetailsUrl = function () {
                        $window.location.href = metUrls('inventoryDetails').concat('/' + scope.item.id);
                    };

                    scope.$watch('selectedPlace.placeName', function (newValue, oldValue) {
                        if (newValue === oldValue || oldValue === undefined || scope.loading) {
                            return;
                        }
                        scope.setSelectedPlace(newValue);
                        scope.saveForm();
                    });

                    scope.$watch('selectedPerson.personName', function (newValue, oldValue) {
                        if (newValue === oldValue || oldValue === undefined || scope.loading) {
                            return;
                        }
                        scope.setSelectedPerson(newValue);
                        scope.saveForm();
                    });

                    scope.$watch('selectedDivision.divisionName', function (newValue, oldValue) {
                        if (newValue === oldValue || oldValue === undefined || scope.loading) {
                            return;
                        }
                        scope.setSelectedDivision(newValue);
                        scope.saveForm();
                    });

                    scope.$watch('itemDetails.category', function (newValue, oldValue) {
                        if (newValue === oldValue || oldValue === undefined || scope.loading) {
                            return;
                        }
                        var category = scope.categories.filter(function (obj) {
                            return obj.categoryName === newValue;
                        });
                        if (category.length > 0) {
                            scope.itemDetails.category = category[0];
                            scope.item.category = scope.getCategoryName(category[0]);
                        }
                        if (newValue.categoryId === -2) {
                            createCategoryModal(oldValue);
                        }
                    });

                    scope.$watch('itemDetails.manufacturer', function (newValue, oldValue) {
                        if (newValue === oldValue || oldValue === undefined || scope.loading) {
                            return;
                        }
                        if (newValue.manufacturerId === -2) {
                            createManufacturerModal(oldValue);
                        }
                    });

                    scope.$watch('itemDetails.serviceDate', function (newValue, oldValue) {
                        if (newValue === oldValue || scope.loading) {
                            return;
                        }
                        else {
                            scope.item.serviceDate = newValue;
                            scope.serviceDateByRegion = newValue ? moment(newValue).format(metDates.date(false)) : null;
                        }
                    });

                    scope.$watch('itemDetails.serviceAlertFrequency', function (newValue, oldValue) {
                        if (newValue === oldValue || scope.loading) {
                            return;
                        }
                        else {
                            scope.item.serviceAlertFrequency = newValue;
                        }
                    });

                    scope.saveDatePicker = function () {
                        var serviceDate = document.querySelector('#serviceDatePicker').value;
                        scope.itemDetails.serviceDate = serviceDate.length > 0 ? moment(serviceDate, metDates.date(false)).format(metDates.api) : undefined;
                        scope.saveForm();
                    };

                    scope.rightCardControl = function (id) {
                        var elements = document.getElementById("rightTabContent").getElementsByClassName("tab-pane");
                        _.forEach(elements, function (element) {
                            element.style.display = "none";
                        });

                        var selectedElement = document.getElementById(id);
                        selectedElement.style.display = "block";
                    };

                    scope.leftCardControl = function (id) {
                        var elements = document.getElementById("leftTabContent").getElementsByClassName("tab-pane");
                        _.forEach(elements, function (element) {
                            element.style.display = "none";
                        });

                        var selectedElement = document.getElementById(id);
                        selectedElement.style.display = "block";
                    };

                    scope.updateError = false;
                    scope.errorMessage = "";

                    scope.saveForm = function () {
                        scope.itemDetails.manufacturerId = scope.itemDetails.manufacturer.manufacturerId;
                        scope.item.manufacturer = scope.itemDetails.manufacturer.manufacturerName;

                        scope.itemDetails.categoryId = scope.itemDetails.category.categoryId;
                        scope.item.category = scope.itemDetails.category.categoryName;
                        
                        scope.item.locationId = scope.selectedPlace.placeId;
                        scope.itemDetails.location = scope.selectedPlace;
                        scope.item.location = scope.itemDetails.place.placeName;
                        scope.itemDetails.placeId = scope.selectedPlace.placeId;
                        scope.item.place = scope.selectedPlace.placeName;
                        
                        scope.itemDetails.divisionId = scope.selectedDivision.divisionId;
                        scope.itemDetails.division = scope.selectedDivision;
                        scope.item.division = scope.selectedDivision.divisionName;
                        scope.item.divisionId = scope.selectedDivision.divisionId;

                        scope.itemDetails.personId = scope.selectedPerson.personId;
                        scope.itemDetails.person = scope.selectedPerson;
                        scope.item.person = scope.selectedPerson.personName;

                        scope.item.toolNumber = scope.itemDetails.toolNumber;
                        scope.item.modelNumber = scope.itemDetails.modelNumber;
                        scope.item.model = scope.itemDetails.modelNumber;
                        scope.item.description = scope.itemDetails.itemDescription;
                        scope.item.category = scope.getCategoryName(scope.itemDetails.category);

                        scope.itemDetails.status = scope.selectedStatus.statusId;
                        scope.itemDetails.statusName = scope.selectedStatus.statusName;
                        scope.item.statusId = scope.itemDetails.status;
                        scope.item.status = scope.selectedStatus.statusName;

                        scope.item.purchaseLocation = scope.itemDetails.purchaseLocation;
                        scope.item.purchaseDate = scope.itemDetails.datePurchased;
                        scope.item.price = scope.itemDetails.price;

                        metInventory.update(
                            scope.itemDetails,
                            function (data) {
                                scope.updateError = false;
                                scope.detailEditView = false;
                                scope.itemDetails.serialNumberId = data.serialNumberId;
                                scope.item.serialNumber = scope.itemDetails.serialNumber;
                                scope.item.status = data.statusName;
                                scope.item.statusId = data.status;
                                scope.itemDetails.status = data.status;
                                scope.itemDetails.statusName = data.statusName;
                                scope.setSelectedStatus(getStatusById(scope.item.statusId), true);
                            },
                            function (error) {
                                scope.detailEditView = true;
                                scope.updateError = true;
                                scope.errorMessage = error.data.message;
                                $('#serialNumberEditContainer').addClass('md-input-focused md-input-invalid');
                            }
                        );
                    };

                    scope.getCategoryName = function (category) {
                        var categoryName = category.displayName;
                        if (category.displayName === undefined) {
                            categoryName = scope.item.category;
                        }
                        if (category.parentCategoryId !== null) {
                            var parentCategory = scope.categories.filter(function (obj) {
                                return obj.categoryId === category.parentCategoryId;
                            });
                            if (parentCategory.length > 0) {
                                categoryName = parentCategory[0].categoryName + ' - ' + categoryName;
                            }
                        }

                        return categoryName;
                    };

                    scope.onTabChanges = function (currentIndex) {
                        setTabSelectedIndex(currentIndex);
                    };

                    function setSelectedStatus (statusObj, doNotSave) {
                        scope.selectedStatus = statusObj;
                        if (!doNotSave && doNotSave !== undefined) {
                            scope.saveForm();
                        }
                    };

                    scope.setSelectedPlace = function (place) {
                        var selectedPlace = [];
                        angular.copy(scope.filter('filter')(scope.locations, { placeName: place }, true)[0], selectedPlace);
                        scope.selectedPlace = selectedPlace;
                    }

                    scope.setSelectedPerson = function (name) {
                        var selectedPerson = [];
                        angular.copy(scope.filter('filter')(scope.people, { personName: name }, true)[0], selectedPerson);
                        scope.selectedPerson = selectedPerson;
                    }

                    scope.setSelectedDivision = function (name) {
                        var selectedDivision = [];
                        angular.copy(scope.filter('filter')(scope.trades, { divisionName: name }, true)[0], selectedDivision);
                        scope.selectedDivision = selectedDivision;
                    }

                    function openModal() {
                        $modal.open(modalOptionsService.generalErrorModalOptions);
                    }

                    function getStatusById(id) {
                        return scope.filter('filter')(scope.statuses, {statusId: id}, true)[0];
                    }

                    function setTabSelectedIndex(value) {
                        scope.tabSelectedIndex.index = value;
                    }

                    function getUserItem(isCancel) {
                        metUserItems.get(scope.item.id, function (response) {
                            scope.itemDetails = response;
                            scope.selectedPlace = scope.itemDetails.place;
                            scope.selectedPerson = scope.itemDetails.person;
                            scope.selectedDivision = scope.itemDetails.division;
                            scope.showOverviewPanel = scope.itemDetails.cycleInformation !== null && scope.itemDetails.lastSeen === null;
                            var lastSeen = metDates.convertUtcToLocal(scope.item.lastSeen, metDates.longDateTimeFormat);
                            var lastScanned = metDates.convertUtcToLocal(scope.itemDetails.lastScanned, metDates.longDateTimeFormat);
                            if (scope.itemDetails.lastScanned === null || scope.itemDetails.lastSeen >= scope.itemDetails.lastScanned) {
                                scope.lastSeenText = scope.messages.lastSeen.value + ' ' + lastSeen;
                            }
                            if (scope.itemDetails.lastSeen === null || scope.itemDetails.lastSeen < scope.itemDetails.lastScanned) {
                                scope.lastSeenText = scope.messages.lastScanned.value + ' ' + lastScanned;
                                scope.isLatestScanned = true;
                            }
                            if (scope.itemDetails.serviceDate) {
                                var converted = metDates.momentUtcToLocal(scope.itemDetails.serviceDate);
                                scope.serviceDatePicker = converted;
                            }

                            var geocoder = new google.maps.Geocoder;
                            geocodeLatLng(geocoder);

                            if (scope.itemDetails.cycleInformation) {
                                scope.lastSyncDate = metDates.convertUtcToLocal(scope.itemDetails.cycleInformation.lastSync, metDates.longDateTimeFormat);
                            }

                            scope.loading = false;
                            if (isCancel) {
                                scope.detailEditView = false;
                            }
                            var searchTerm = scope.itemDetails.modelNumber;
                            if (searchTerm !== null) {
                                metItems.searchItems(
                                    searchTerm, 0, 10,
                                    function(searchResponse) {
                                        _.forEach(searchResponse.items,
                                            function (match) {
                                                scope.isValidModelNumber = match.modelNumber === scope.item.model;
                                            });
                                    });
                            }

                            scope.timeFromEntry = getTimeOwned();
                            if (scope.itemDetails.imageAlternates && scope.itemDetails.imageAlternates.smallUrl === null) {
                                scope.itemDetails.imageAlternates.smallUrl = '/Content/images/placeholder_other.png';
                            }
                            if (!scope.itemDetails.imageAlternates) {
                                scope.itemDetails.imageAlternates = scope.itemDetails.manufacturer.isPrimary
                                    ? { smallUrl: 'https://onekey-tool-images-na.s3.amazonaws.com/default-images/No%20Image%20Available.jpg' }
                                    : { smallUrl: '/Content/images/placeholder_other.png' }
                            }
                        });
                    }

                    function getTimeOwned() {
                        if (scope.itemDetails.dateAdded) {
                            var langKey = metDates.getLanguageCookies();
                            moment.locale(langKey);
                            var mDateAdded = moment(scope.itemDetails.dateAdded);
                            var adjustedDate = mDateAdded.add(mDateAdded.utcOffset() / 60, 'hours');
                            scope.timeFromEntry = adjustedDate.fromNow();
                        }
                        return scope.timeFromEntry;
                    }

                    var init = function (isCancel) {
                        scope.loadItems();
                        getUserItem(isCancel);
                        setTabSelectedIndex(0);
                        scope.setSelectedStatus(getStatusById(scope.item.statusId));
                        scope.serviceDateByRegion = scope.item.serviceDate ? moment(scope.item.serviceDate).format(metDates.date(false)) : null;
                        scope.updateError = false;
                    };

                    init();

                    function geocodeLatLng(geocoder) {
                        var latitude = scope.itemDetails.hasTickAttached ? scope.itemDetails.tick.latitude : scope.itemDetails.latitude;
                        var longitude = scope.itemDetails.hasTickAttached ? scope.itemDetails.tick.longitude : scope.itemDetails.longitude;

                        if (scope.itemDetails.lastSeen === null || scope.itemDetails.lastSeen < scope.itemDetails.lastScanned) {
                            latitude = scope.itemDetails.scanLatitude;
                            longitude = scope.itemDetails.scanLongitude;
                        }
                        var center = new google.maps.LatLng(latitude, longitude);
                        geocoder.geocode({'location': center}, function (results, status) {

                            if (status === 'OK') {
                                if (results[0]) {
                                    scope.address = results[0].formatted_address;
                                } else {
                                    scope.address = scope.messages.noAddressFound.value;
                                }
                            } else {
                                scope.address = scope.messages.noAddressFound.value;
                            }
                        });
                    }

                    function createPlaceModal(oldValue) {
                        var modalOptions = {
                            templateUrl: metUrls('addLocationModal'),
                            backdrop: true,
                            keyboard: true,
                            modalFade: true,
                            controller: function ($scope, $modalInstance, modalOptionsService) {
                                $scope.modalInit = modalInit;
                                $scope.save = save;
                                $scope.cancel = cancel;

                                function save() {
                                    var locationModel = { placeName: $scope.addLocationForm.location.$modelValue, typeId: 1 };
                                    $scope.saving = true;
                                    metLocations.create(locationModel, function (newLocation) {
                                        scope.itemDetails.place = newLocation;
                                        $modalInstance.close(newLocation);
                                    }, function () {
                                        $scope.saving = false;
                                        $scope.valid = false;
                                        if ($scope.location.placeName === "" || $scope.location.placeName === undefined) {
                                            $scope.duplicate = true;
                                            $scope.error = $scope.modalMessages.required.value;
                                        }
                                        else {
                                            $scope.duplicate = true;
                                            $scope.error = scope.modalMessages.error.value;
                                        }
                                    });
                                }

                                function cancel(reason) {
                                    $modalInstance.dismiss(reason);
                                }

                                function handleError(error) {
                                    $scope.saving = false;
                                    $scope.valid = false;
                                    $scope.duplicate = true;
                                    $scope.error = error.data.message === undefined ? error.data : error.data.message;
                                }

                                function modalInit() {
                                    $scope.modalMessages = modalOptionsService.locationModalOptions.messages;
                                }
                            },
                        };
                        var modalInstance = $modal.open(modalOptions);

                        modalInstance.result.then(function (response) {
                            scope.locations.push(response.toJSON());
                            scope.myModel = response.toJSON();
                            scope.setSelectedPlace(response.toJSON().placeName);
                        }, function () {
                            scope.itemDetails.place = oldValue;
                        });
                    }

                    function createPersonModal(oldValue) {
                        var modalOptions = modalOptionsService.personModalOptions;
                        modalOptions.controller = function ($scope, $modalInstance) {
                            $scope.save = save;
                            $scope.cancel = cancel;
                            $scope.personInit = personInit;
                            function save() {
                                metPeople.create($scope.person, function (newPerson) {
                                    scope.itemDetails.person = newPerson;
                                    $modalInstance.close(newPerson);
                                }, function () {
                                    $scope.saving = false;
                                    $scope.valid = false;
                                    if ($scope.person.personName === "" || $scope.person.personName === undefined) {
                                        $scope.duplicate = true;
                                        $scope.error = $scope.messages.required.value;
                                    }
                                    else {
                                        $scope.duplicate = true;
                                        $scope.error = $scope.messages.error.value;
                                    }
                                });
                            }

                            function cancel(reason) {
                                $modalInstance.dismiss(reason);
                            }

                            function personInit() {
                                $scope.messages = modalOptionsService.personModalOptions.messages;
                            }
                        };
                        var modalInstance = $modal.open(modalOptions);

                        modalInstance.result.then(function (success) {
                            scope.people.push(success.toJSON());
                            scope.setSelectedPerson(success.toJSON().personName);
                        }, function (error) {
                            scope.itemDetails.person = oldValue; 
                            scope.error = error;
                        });
                    }

                    function createDivisionModal(oldValue) {
                        var modalOptions = modalOptionsService.sharedDefaultOptions;
                        modalOptions.templateUrl = metUrls('addTradeModal');
                        var modalInstance = $modal.open(modalOptions);

                        modalInstance.result.then(function (success) {
                            scope.trades.push(success.toJSON());
                            scope.setSelectedDivision(success.toJSON().divisionName);
                        }, function () {
                            scope.itemDetails.division = oldValue;
                        });
                    }

                    function createCategoryModal(oldValue) {
                        var modalOptions = modalOptionsService.sharedDefaultOptions;
                        modalOptions.templateUrl = metUrls('addCategoryModal');
                        var modalInstance = $modal.open(modalOptions);

                        modalInstance.result.then(function (result) {
                            scope.itemDetails.category = result;
                            getCategories();
                            scope.categories.push(result);
                        }, function () {
                            scope.itemDetails.category = oldValue;
                        });
                    }

                    function createManufacturerModal(oldValue) {
                        var modalOptions = modalOptionsService.sharedDefaultOptions;
                        modalOptions.templateUrl = metUrls('addManufacturerModal');
                        var modalInstance = $modal.open(modalOptions);

                        modalInstance.result.then(function (success) {
                            scope.itemDetails.manufacturer = success;
                        }, function () {
                            scope.itemDetails.manufacturer = oldValue;
                        });
                    }

                    function getCategories() {
                        metCategories.getAll({
                            includeUncategorized: true
                        },
                            function (data) {
                                var categories = [];
                                scope.parentCategories = [];
                                _.forEach(data.items, function (category) {
                                    category.displayName = category.categoryName;
                                    categories.push(category);
                                    scope.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);
                                    });
                                });

                                scope.categories = categories;;
                                var newCategory = {
                                    categoryName: scope.messages.addCategoryOption.value,
                                    categoryId: -2,
                                    childCategories: null
                                };
                                scope.categories.unshift(newCategory);
                                _.forEach(scope.categories, function (item) {
                                    if (item.childCategories !== null && item.childCategories.length > 0) {
                                        _.forEach(item.childCategories, function (childCategory) {
                                            childCategory.childCategories = [];
                                            childCategory.categoryName = item.categoryName + ' ' + childCategory.categoryName;

                                            var index = scope.categories.map(function (category) { return category.categoryId; }).indexOf(childCategory.categoryId);
                                            scope.categories.splice(index, 1);
                                            scope.categories.push(childCategory);
                                        });
                                    }
                                });
                            });
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metGridPaging', [
        'urls', 'localize', 'inventoryGridConfig', 'host', '$window',
        function (metUrls, metLocalize, metInventoryGrid, host, $window) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryGridPagingHtml'),
                scope: {
                    updateResults: '&',
                    isBottom: '@',
                    loading: '=',
                    showPaging: '=',
                    label: '@'
                },
                link: function (scope, element, attrs) {
                    scope.messages = {
                        of: metLocalize('messages', 'of'),
                        totalTools: metLocalize('fieldNames', 'totalTools'),
                        tools: metLocalize('fieldNames', 'tools'),
                        resultsPerPage: metLocalize('messages', 'resultsPerPage')
                    };
                    
                    scope.totalResults = 0;
                    scope.startNumber = 0;
                    scope.pageNumbers = [];
                    scope.currentPage = 1;
                    scope.totalPages;
                    scope.endNumber;
                    scope.showForwardPageSet = true;
                    scope.showPreviousPageSet = true;
                    scope.resultsPerPage = metInventoryGrid.resultsPerPage;

                    var userAgent = $window.navigator.userAgent;
                    var browsers = { chrome: /chrome/i, safari: /safari/i, firefox: /firefox/i };
                    var notIe = false;
                    for (var key in browsers) {
                        if (browsers[key].test(userAgent)) {
                            notIe = true;
                        }
                    };
                    scope.resultsPerPageOptions = notIe === false ? [10, 25, 50] : [10, 25, 50, 100, 200];

                    scope.changeResultsPerPage = function (resultOption) {
                        scope.resultsPerPage = resultOption;
                        metInventoryGrid.setResultsPerPage(resultOption);
                        scope.updateResults();
                    }
                    
                    scope.$on('grid-updated', function (event, args) {
                        scope.totalResults = args.totalResults;
                        scope.startNumber = args.startNumber;
                        scope.currentPage = args.currentPage;
                        var element = document.getElementById('totalTools');
                        if (element) {
                            metLocalize('fieldNames', 'totalTools').promise.then(function (val) {
                                element.innerHTML = val + '<br/><span>' + scope.totalResults + '</span>';
                            });
                        }
                        getEndNumber(args.resultsPerPage);

                        if (scope.showPaging) {
                            scope.showForwardPageSet = true;
                            scope.showPreviousPageSet = true;
                            getPageNumbers();
                        }
                    });

                    function getEndNumber(resultsPerPage) {
                        var endNumber = scope.startNumber - 1 + resultsPerPage;
                        if (endNumber > scope.totalResults) {
                            endNumber = scope.totalResults;
                        }
                        scope.endNumber = endNumber;
                    }

                    function getPageNumbers() {
                        scope.pageNumbers = [];
                        scope.totalPages = parseInt(scope.totalResults / metInventoryGrid.resultsPerPage);
                        if ((scope.totalResults % metInventoryGrid.resultsPerPage) > 0) {
                            scope.totalPages++;
                        }

                        var startPage = (parseInt((scope.currentPage - 1) / 10) * 10) + 1;
                        if (startPage === 1) {
                            scope.showPreviousPageSet = false;
                        }

                        var endPage = startPage + 9;
                        if (endPage >= scope.totalPages) {
                            scope.showForwardPageSet = false;
                            endPage = scope.totalPages;
                        }
                        for (var i = startPage; i <= endPage; i++) {
                            scope.pageNumbers.push(i);
                        }
                    }

                    scope.goToPage = function (pageNumber) {
                        metInventoryGrid.pageIndex = pageNumber - 1;
                        scope.updateResults({ isPaging: true });
                    }

                    scope.previousPageSets = function () {
                        var firstPageNumber = scope.pageNumbers[0] - 1;
                        scope.goToPage(firstPageNumber);
                    }

                    scope.forwardPageSets = function () {
                        var lastPageNumber = scope.pageNumbers[scope.pageNumbers.length - 1] + 1;
                        scope.goToPage(lastPageNumber);
                    }

                    scope.goTo = function () {
                        var inputElement = document.getElementById('pageNumber');
                        var pageNumber = parseInt(inputElement.value);
                        var inRange = function() {
                            return pageNumber <= scope.totalPages && pageNumber > 0;
                        }

                        if (inRange()) {
                            scope.goToPage(pageNumber);
                        }
                        else {
                            if (pageNumber > scope.totalPages) {
                                scope.goToPage(scope.totalPages);
                            }
                            else {
                                scope.goToPage(1);
                            }
                        }
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metItemResources', [
        'urls', 'localize', 'dates',
        function (metUrls, metLocalize, metDates) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('itemResources'),
                scope: {
                    item: '='
                },
                link: function (scope, element, attrs) {
                    scope.messages = {
                        date: metLocalize('fieldNames', 'date'),
                        itemValue: metLocalize('fieldNames', 'ItemValue'),
                        serviceType: metLocalize('fieldNames', 'serviceType'),
                        location: metLocalize('fieldNames', 'place'),
                        purchaseInformation: metLocalize('fieldNames', 'purchaseInformation')
                    }
                    

                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metServiceRecord', [
        '$compile', 'urls', 'localize', 'dates', 'serviceRecords', 'itemStatuses', 'notify',
        function ($compile, metUrls, metLocalize, metDates, metServiceRecordService, itemStatuses, metNotify) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('serviceRecord'),
                scope: {
                    item: '='
                },
                link: function (scope, element) {
                    scope.messages = {
                        date: metLocalize('fieldNames', 'date'),
                        cost: metLocalize('fieldNames', 'cost'),
                        serviceType: metLocalize('fieldNames', 'serviceType'),
                        serviceRecord: metLocalize('fieldNames', 'serviceRecord'),
                        servicedBy: metLocalize('fieldNames', 'servicedBy'),
                        notes: metLocalize('fieldNames', 'notes'),
                        addRecord: metLocalize('fieldNames', 'addRecord'),
                        addServiceRecord: metLocalize('commands', 'addRecord_AllCaps'),
                        everythingInOneSpot: metLocalize('messages', 'everythingInOneSpot'),
                        emptyServiceRecordText: metLocalize('messages', 'emptyServiceRecordText'),
                        createRecord: metLocalize('commands', 'createRecord'),
                        delete: metLocalize('commands', 'delete'),
                        deleteConfirm: metLocalize('messages', 'deleteUploadConfirm'),
                        edit: metLocalize('commands', 'edit'),
                        view: metLocalize('commands', 'view'),
                        uploads: metLocalize('fieldNames', 'uploads')
                    };
                    if (!scope.serviceRecords) {
                        scope.serviceRecords = [];
                    }
                    scope.serviceTypes = '';
                    scope.emptyServiceRecords = false;
                    scope.statuses = [];
                    scope.dateFormat = metDates.date(true);
                    scope.hasUploads = false;

                    scope.createRecord = createRecord;
                    scope.getContainer = getContainer;
                    scope.hideAddDialog = hideAddDialog;
                    scope.showAddDialog = showAddDialog;
                    scope.deleteServiceRecord = deleteServiceRecord;
                    scope.refreshServiceRecords = refreshServiceRecords;
                    var statuses = itemStatuses.getAll();
                    statuses.$promise.then(function (data) {
                        _.forEach(data.items, function (status) {

                            scope.statuses.push(status);
                        });
                    });
                    scope.item.statuses = scope.statuses;
                    
                    scope.emptyServiceRecords = false;

                    metServiceRecordService.getAllByUserItemId(scope.item.id, function (data) {
                        scope.serviceRecords = data;
                        for (var i = 0; i < scope.serviceRecords.length; i++) {
                            scope.serviceRecords[i].localDate = metDates.convertUtcToLocal(scope.serviceRecords[i].date, scope.dateFormat);
                            scope.serviceRecords[i].cost =
                                scope.serviceRecords[i].cost === null ? 0 : scope.serviceRecords[i].cost;
                            for (var z = 0; z < scope.serviceRecords[i].serviceRecordUploads.length; z++) {
                                scope.serviceRecords[i].serviceRecordUploads[z].createdOnLocal = metDates.convertUtcToLocal(scope.serviceRecords[i].serviceRecordUploads[z].createdOn, scope.dateFormat);
                            }
                        }
                        scope.emptyServiceRecords = scope.serviceRecords.length <= 0;
                    }, function (error) { console.log(error) });

                    metServiceRecordService.getTypes(function (data) {
                        scope.serviceTypes = data;
                    }, function (error) { console.log(error) });

                    scope.getTypeForRecords = function (typeId) {
                        var desc = "";
                        angular.forEach(scope.serviceTypes, function (recordType) {
                            if (parseInt(recordType.id) == typeId)
                                desc = recordType.name;
                        });

                        return desc;
                    }
                    scope.serviceTypes =
                        scope.serviceRecords = [];

                    function createRecord(serviceRecord) {
                        var result = metServiceRecordService.create(serviceRecord);
                        result.$promise.then(function (response) {
                            console.log(response.data);
                        });
                    }
                    scope.editServiceRecord = function (selectedServiceRecord) {
                        console.log('in edit view');
                        scope.isEdit = true;
                        scope.selectedRecord = selectedServiceRecord;
                        scope.hasUploads = scope.selectedRecord.serviceRecordUploads.length > 0;
                        var container = getContainer();
                        var el = $compile('<met-add-edit data-item="item" data-service-record-items="serviceRecords" selected-record="selectedRecord" data-has-uploads="hasUploads" data-reload-records="refreshServiceRecords"></met-add-edit>')(scope);
                        container.append(el);
                        showEditDialog(container, selectedServiceRecord);
                    }
                    
                    scope.addServiceRecord = function () {
                        scope.isEdit = false;
                        var container = getContainer();
                        scope.selectedRecord = undefined;
                        scope.hasUploads = false;
                        var el = $compile('<met-add-edit data-item="item" data-service-record-items="serviceRecords" selected-record="selectedRecord" data-has-uploads="hasUploads" data-reload-records="refreshServiceRecords" data-empty-service-records="emptyServiceRecords"></met-add-edit>')(scope);
                        container.append(el);
                        showAddDialog(container);
                    }
                    
                    function getContainer() {
                        return element.parents('.item-container');
                    }

                    function showEditDialog(container, selectedServiceRecord) {

                        container.children().css('display', 'none');
                        $('#oneKeyAddEditContainer').css('display', 'table-cell');
                        scope.serviceRecord = selectedServiceRecord;
                    }

                    function showAddDialog(container) {
                        container.children().css('display', 'none');
                        $('#oneKeyAddEditContainer').css('display', 'table-cell');

                    }

                    function hideAddDialog(container) {
                        container.children().css('display', 'block');
                        $('#oneKeyAddEditContainer').remove();
                    }

                    function refreshServiceRecords() {
                        metServiceRecordService.getAllByUserItemId(scope.item.id,
                            function (response) {
                                scope.serviceRecords = response.data;
                                for (var i = 0; i < scope.serviceRecords.length; i++) {
                                    for (var z = 0; z < scope.serviceRecords[i].serviceRecordUploads.length; z++) {
                                        scope.serviceRecords[i].serviceRecordUploads[z].createdOnLocal = metDates.convertUtcToLocal(scope.serviceRecords[i].serviceRecordUploads[z].createdOn, scope.dateFormat);
                                    }
                                }
                                var container = scope.getContainer();
                                scope.hideAddDialog(container);
                            },
                            function (response) {
                                console.log(response.message);
                            });
                    }


                    scope.cancel = function () {
                        var container = scope.getContainer();
                        scope.hideAddDialog(container);
                    };

                    scope.update = function (serviceRecord) {
                        serviceRecords.update(serviceRecord,
                            function (serviceRecord) {
                                scope.original = null;
                                metNotify.success(serviceRecord.Id + 'updated successfully');
                            },
                            function (error) {
                                serviceRecord.error = error.data.message;
                            });
                    };

                    function deleteServiceRecord(serviceRecordId) {
                        metServiceRecordService.remove(serviceRecordId,
                            function (response) {
                                if (response.$resolved) {
                                    scope.serviceRecords = scope.serviceRecords.filter(function(deletedRecord) {
                                        return deletedRecord.id !== serviceRecordId;
                                    });
                                }
                                scope.emptyServiceRecords = scope.serviceRecords.length === 0;
                            },
                            function (response) {
                                metNotify.error(response.data.message);
                            });

                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metBoolFilter', [
        'urls', 'localize', 'inventoryFilters',
        function (metUrls, metLocalize, metInventoryFilters) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryBoolFilterHtml'),
                scope: true,
                link: function (scope, element, attrs) {
                    scope.boolMessages = {
                        yesLabel: metLocalize('commands', 'yes'),
                        noLabel: metLocalize('commands', 'no'),
                        selectedTrueLabel: metLocalize('messages', 'MaintenanceNeeded'),
                        selectedFalseLabel: metLocalize('messages', 'NoMaintenanceNeeded')
                    }

                    scope.modalChanged = function () {
                        if (scope.filter.value != undefined) {
                            var selectedLabel = scope.filter.value == true ? scope.boolMessages.selectedTrueLabel.value : scope.boolMessages.selectedFalseLabel.value;
                            metInventoryFilters.addSelectedFilter(scope.filter.name, 1, selectedLabel);
                        } else {
                            metInventoryFilters.removeSelectedFilter(scope.filter.name, 1);
                        }
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metDateRangeFilter', [
        'urls', 'localize', 'inventoryFilters',
        function (metUrls, metLocalize, metInventoryFilters) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryDateRangeFilterHtml'),
                scope:true,
                link: function (scope, element, attrs) {
                    var filterLabel = "";
                    switch (scope.filter.name) {
                        case "lastSeen":
                            filterLabel = "lastSeenRange";
                            break;
                        case "purchaseDate":
                            filterLabel = "purchaseDateRange";
                            break;
                    }

                    scope.dateMessages = {
                        filterLabel: metLocalize('messages', filterLabel),
                        sevenDays: metLocalize('fieldNames', "lastSevenDays"),
                        thirtyDays: metLocalize('fieldNames', "lastThirtyDays"),
                        sixtyDays: metLocalize('fieldNames', "lastSixtyDays"),
                        ninetyDays: metLocalize('fieldNames', "lastNinetyDays"),
                    };

                    scope.modalChanged = function () {
                        var label = scope.dateMessages.filterLabel.value.replace("{0}", scope.filter.value);
                        if (scope.filter.value != undefined) {
                            metInventoryFilters.addSelectedFilter(scope.filter.name, 1, label);
                        } else {
                            metInventoryFilters.removeSelectedFilter(scope.filter.name, 1);
                        }
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metFilters', [
        '$filter', 'urls', 'localize', 'itemFieldFactory', 'inventoryFilters',
        function ($filter, metUrls, metLocalize, metItemFields, metInventoryFilters) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryFiltersHtml'),
                scope: {
                    updateResults: '&',
                    showHideFilters: '&',
                    region: '=',
                    categories: '&',
                    oneKey: '&'
                },
                link: function (scope, element, attrs) {
                    scope.filterMessages = {
                        update: metLocalize('commands', 'update'),
                        closeFilters: metLocalize('commands', 'closeFilters'),
                        clearAll: metLocalize('commands', 'ClearAll'),
                        oneKey: metLocalize('titles', 'oneKey'),
                        oneKeyText: metLocalize('titles', 'oneKeyText'),
                        oneKeyOnly: $('#oneKeyOnlyString').val(),
                        oneKeyOnlyText: metLocalize('fieldNames', 'oneKeyOnlyText'),
                        tickOnly: $('#tickString').val(),
                        tickOnlyText: metLocalize('fieldNames', 'tickOnlyText')
                    }

                    scope.showHideOneKeyFilter = function () {
                        var isOpened = scope.oneKey.isOpened;
                        scope.oneKey.isOpened = !isOpened;
                    }
                   
                    var priceItems = [
                        { id: 1, label: $('#lessThanFiftyString').val() },
                        { id: 2, label: $('#fiftyToHundredString').val() },
                        { id: 3, label: $('#hundredToTwoFiftyString').val() },
                        { id: 4, label: $('#twoFiftyToFiveHundredString').val() },
                        { id: 5, label: $('#aboveFiveHundredString').val() }
                    ]

                    metItemFields.values = priceItems;
                    metInventoryFilters.createFilters(metItemFields);
                    scope.filters = metInventoryFilters.filters;
                    scope.itemFields = metItemFields;
                    metInventoryFilters.closeAllFilters();
                    scope.inventoryFilters = metInventoryFilters;

                    scope.oneKeyOnlyChanged = function (id) {
                        if (id) {
                            scope.toggleCheckbox(document.getElementById(id));
                        }

                        if (scope.inventoryFilters.oneKeyOnly) {
                            metInventoryFilters.addSelectedFilter("oneKeyOnly", 1, scope.filterMessages.oneKeyOnly);
                        } else {
                            metInventoryFilters.removeSelectedFilter("oneKeyOnly", 1);
                        }
                    }

                    scope.tickOnlyChanged = function (id) {
                        if (id) {
                            scope.toggleCheckbox(document.getElementById(id));
                        }

                        if (scope.inventoryFilters.tickOnly) {
                            metInventoryFilters.addSelectedFilter("tickOnly", 1, scope.filterMessages.tickOnly);
                        } else {
                            metInventoryFilters.removeSelectedFilter("tickOnly", 1);
                        }
                    }

                    scope.toggleCheckbox = function (checkbox) {
                        checkbox.click();
                    }

                    scope.updateFilterResults = function () {
                        scope.updateResults();
                    }

                    scope.removeAllFilters = function () {
                        metInventoryFilters.removeAllFilters();
                        metInventoryFilters.nukeFilters();
                        scope.updateResults();
                    }

                    scope.init = true;

                    scope.selectedFilterItems = JSON.parse(localStorage.getItem("selectedFilters"));

                    scope.initialize = function () {
                        if (scope.selectedFilterItems != null) {
                            for (var i = 0; i < scope.selectedFilterItems.length; i++) {
                                if (scope.selectedFilterItems[i].filterName == "oneKeyOnly") {
                                    scope.inventoryFilters.oneKeyOnly = true;
                                }
                                if (scope.selectedFilterItems[i].filterName == "tickOnly") {
                                    scope.inventoryFilters.tickOnly = true;
                                }
                            }
                        }
                    }
                    scope.initialize();
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metFilterSelector', [
        '$filter', 'urls', 'localize', 'dates', 'inventoryFilters',
        function ($filter, metUrls, metLocalize, metDates, metInventoryFilters) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryFilterSelector'),
                scope: {
                    filter: '=metFilter',
                },
                link: function (scope, element, attrs) {
                    scope.filterLabel = metLocalize('fieldNames', scope.filter.label);
                    scope.datePickerOptions = metDates.getDatePickerOptions();

                    scope.showHideFilter = function () {
                        var isOpened = scope.filter.isOpened;
                        scope.filter.isOpened = !isOpened;
                    }

                    scope.selectedFilters = JSON.parse(localStorage.getItem("selectedFilters"));

                    scope.showSelectedLabel = false;
                    scope.selectedLabel = function () {
                        var label = "";
                        switch (scope.filter.filterType) {
                            case "list":
                                if (scope.selectedFilters.length != 0) {
                                    label = $filter('filter')(scope.selectedFilters, { isSelected: true, filterName: scope.filter.name }).length.toString();
                                    break;
                                }
                                label = $filter('filter')(scope.filter.items, { isSelected: true }).length.toString();
                                break;
                            case "date":
                            case "bool":
                                if (scope.selectedFilters.length != 0) {
                                    label = $filter('filter')(scope.selectedFilters, { isSelected: true, filterName: scope.filter.name }).length.toString();
                                    break;
                                }
                                if (scope.selectedFilters.length == 0) {
                                    label = scope.filter.value == undefined ? "0" : "1";
                                    break;
                                }
                                label = scope.filter.value == undefined ? "0" : "1";
                                break;
                        }

                        scope.showSelectedLabel = label.length > 0 && label != "0";
                        return label;
                    }

                    scope.updateSelectedLabel = function (label) {
                        scope.selectedLabel = label;
                    }
                    
                    scope.labelClicked = function (item) {
                        item.isSelected = !item.isSelected;
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metItemFilter', [
        '$filter', 'urls', 'inventoryFilters', 'localize',
        function ($filter, metUrls, metInventoryFilters, metLocalize) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryItemFilterHtml'),
                scope: {
                    filter: '='
                },
                link: function (scope, element, attrs) {
                    scope.messages = {
                        search: metLocalize('commands', 'search'),
                    }

                    scope.labelClicked = function (item) {
                        if (!scope.isDisabled(item[scope.filter.itemIdProperty])) {
                            item.isSelected = !item.isSelected;
                            scope.itemChange(item);
                        }
                    }

                    scope.itemChange = function (item) {
                        if (item.isSelected) {
                            metInventoryFilters.addSelectedFilter(scope.filter.name, item[scope.filter.itemIdProperty], item[scope.filter.itemLabelProperty]);
                        } else {
                            metInventoryFilters.removeSelectedFilter(scope.filter.name, item[scope.filter.itemIdProperty]);
                        }
                    }

                    scope.selectedFilterItems = JSON.parse(localStorage.getItem("selectedFilters"));

                    scope.isDisabled = function (id) {
                        if (scope.filter.enabledItems !== undefined) {
                            return scope.filter.enabledItems.indexOf(id) == -1;
                        }
                    }

                    scope.initialize = function (item) {
                        for (var i = 0; i < scope.selectedFilterItems.length; i++) {
                            if (item[scope.filter.itemLabelProperty] == scope.selectedFilterItems[i].label ) {
                                item.isSelected = scope.selectedFilterItems[i].isSelected;
                            }
                        }
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metQuickFilters', [
        '$filter', 'urls', 'localize', 'itemFieldFactory', 'inventoryFilters', 'featureToggle',
        function ($filter, metUrls, metLocalize, metItemFields, metInventoryFilters, featureToggle) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryQuickFiltersHtml'),
                scope: {
                    updateResults: '&',
                    showHideFilters: '&',
                    region: '=',
                    categories: '&'
                },
                link: function (scope, element, attrs) {
                    scope.filterMessages = {
                        markedMissing: metLocalize('fieldNames', 'markedMissing'),
                        unseen: metLocalize('fieldNames', 'unseenFiveDays'),
                        upcomingService: metLocalize('fieldNames', 'upcomingService'),
                        pastDueService: metLocalize('fieldNames', 'pastDueService'),
                        oneKeyItem: metLocalize('messages', 'oneKeyItem'),
                        seenOutsideGeofence: metLocalize('messages', 'seenOutsideGeofence'),
                        needsService: metLocalize('messages', 'needsService')
                    }
                    featureToggle.getAll()
                        .then(function (response) {
                            scope.enableGeofence = response.geofence;
                        });
                    scope.markedMissing = function () {
                        var element = document.getElementById("markedMissing");
                        var sideNavElement = document.getElementById("status_1");
                        if (element.checked) {
                            metInventoryFilters.addSelectedFilter("status", 1, "Missing", true);
                            sideNavElement.checked = true;
                        } else {
                            metInventoryFilters.removeSelectedFilter("status", 1);
                            sideNavElement.checked = false;
                        }
                        setTimeout(function () { scope.updateResults();}, 300);
                    }

                    scope.upcomingService = function () {
                        var element = document.getElementById("hasUpcomingService");
                        if (element.checked) {
                            metInventoryFilters.addSelectedFilter("maintenance", 1, "maintenanceNeeded", true, true);
                        } else {
                            metInventoryFilters.removeSelectedFilter("maintenance", 1);
                        }
                        setTimeout(function () { scope.updateResults(); }, 300);
                    }

                    scope.unseen = function () {
                        var element = document.getElementById("unseen");
                        if (element.checked) {
                            metInventoryFilters.addSelectedFilter("unseen", 1, "unseen", true, 5);
                        } else {
                            metInventoryFilters.removeSelectedFilter("unseen", 1);
                        }
                        setTimeout(function () { scope.updateResults(); }, 300);
                    }

                    scope.outsideGeofence = function () {
                        var element = document.getElementById("outsideGeofence");
                        if (element.checked) {
                            metInventoryFilters.addSelectedFilter("outsideGeofence", 1, "outsideGeofence", true, true);
                        } else {
                            metInventoryFilters.removeSelectedFilter("outsideGeofence", 1);
                        }
                        setTimeout(function () { scope.updateResults(); }, 300);
                    }


                    scope.updateFilterResults = function () {
                        scope.updateResults();
                    }

                    scope.init = true;

                    scope.selectedFilterItems = JSON.parse(localStorage.getItem("selectedFilters"));

                    scope.initialize = function () {

                        if (scope.selectedFilterItems !== null) {
                            for (var i = 0; i < scope.selectedFilterItems.length; i++) {
                                if ("Missing" === scope.selectedFilterItems[i].label) {
                                    var missingElement = document.getElementById("markedMissing");
                                    missingElement.checked = true;
                                }
                                if ("maintenanceNeeded" === scope.selectedFilterItems[i].label) {
                                    var upcomingServiceElement = document.getElementById("hasUpcomingService");
                                    upcomingServiceElement.checked = true;
                                }
                                if ("pastDueService" === scope.selectedFilterItems[i].label) {
                                    var pastDueServiceElement = document.getElementById("pastDueService");
                                    pastDueServiceElement.checked = true;
                                }
                                if ("unseen" === scope.selectedFilterItems[i].label) {
                                    var unseenElement = document.getElementById("unseen");
                                    unseenElement.checked = true;
                                }
                                if ("outsideGeofence" === scope.selectedFilterItems[i].label) {
                                    var outsideGeofenceElement = document.getElementById("outsideGeofence");
                                    outsideGeofenceElement.checked = true;
                                }
                            }
                        }
                    }

                    scope.initialize();
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metSelectedFilters', [
        '$filter', 'urls', 'inventoryFilters',
        function ($filter, metUrls, metInventoryFilters) {
            return {
                restrict: 'E',
                replace: true,
                scope: {
                    selectedFilters: '=',
                    updateResults: '&'
                },
                templateUrl: metUrls('inventorySelectedFiltersHtml'),
                link: function (scope, element, attrs) {

                    scope.showSelectedFilters = function () {
                        return $filter('filter')(scope.selectedFilters, { isSaved: true });
                    }

                    scope.quickRemoveFilter = function (selectedFilter) {
                        metInventoryFilters.quickRemoveFilter(selectedFilter);
                        setTimeout(function () { scope.updateResults(); }, 500);
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metInventoryOverTimeGraph', [
        'urls', 'localize', 'dates', '$modal', 'modalOptionsService', 'historyService',
        function (metUrls, metLocalize, metDates, $modal, modalOptionsService, metHistoryService) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryOverTimeGraphHtml'),
                scope: {
                    item: '=',
                    chartConfig: '='
                },
                link: function (scope) {
                    scope.refreshChart = refreshChart;
                    scope.initialize = initialize;
                    scope.metHistoryService = metHistoryService;
                    scope.seriesName = '';
                    scope.currentSeriesData = [];
                    scope.iotOptions = {};
                    scope.iotChart;
                    scope.messages = {
                        from: metLocalize('commands', 'from'),
                        to: metLocalize('commands', 'to'),
                        inventoryDashboard: metLocalize('titles', 'inventoryDashboard'),
                        inventoryOverTime: metLocalize('titles', 'inventoryOverTime')
                    };

                    scope.iotOptions = {
                        chart: {
                            renderTo: 'inventoryOverTimeChartContainer',
                            zoomType: 'x',
                            width: 450,
                            height: 350
                        },
                        credits: {
                            enabled: false
                        },
                        legend: {
                            enabled: false
                        },
                        title: {
                            text: '',
                            y: 0
                        },
                        xAxis: {
                            type: 'datetime'
                        },
                        yAxis: {
                            id: 'inventoryCount',
                            allowDecimals: false,
                            title: {
                                text: ''
                            }
                        },
                        series: [{
                            id: 'iotData',
                            name: '',
                            type: 'line',
                            data: scope.currentSeriesData
                        }],
                        loading: false
                    };

                    // -- the Highcharts namespace is exported from the Highcharts library - no other declaration is needed
                    scope.iotChart = new Highcharts.Chart(scope.iotOptions);

                    function getFormattedSeriesData(data) {
                        return data.history.map(function (obj) {
                            return [moment(obj.date).valueOf(), obj.count];
                        });
                    }

                    function refreshChart() {
                        scope.metHistoryService.getHistoricalData()
                            .then(
                            function (data) {
                                if (data.status === 200) {
                                    scope.currentSeriesData = getFormattedSeriesData(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);
                                    });
                                } else {
                                    openModal();
                                }
                            },
                            function () {
                                openModal();
                            }
                        );
                    }

                    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) {
                        return dateItem ? moment(dateItem).format(metDates.date(false)) : 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, index) {
                        var seriesDef = {
                            id: 'iotData',
                            name: scope.seriesName,
                            type: 'line',
                            data: seriesArray
                        }
                        var seriesData = scope.iotChart.get('iotData');
                        seriesData.update(seriesDef, true);
                    }

                    function setYAxisTitle(titleText) {
                        var yAxis = scope.iotChart.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 initialize() {
                        scope.refreshChart();
                    };

                    initialize();
                }
            };
        }
    ]);
}());

(function() {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metToolsByCategoryGraph',
        [
            'urls', 'localize', 'dates', '$modal', 'modalOptionsService', 'stats', 'inventoryFilters',
            function(metUrls,
                metLocalize,
                metDates,
                $modal,
                modalOptionsService,
                metStatsService,
                metInventoryFilters) {
                return {
                    restrict: 'E',
                    replace: true,
                    templateUrl: metUrls('toolsByCategoryGraphHtml'),
                    scope: {
                        updateResults: '&',
                        item: '=',
                        chartConfig: '=',
                        refreshChart: '='
                    },
                    link: function(scope) {
                        scope.metStatsService = metStatsService;
                        scope.categories = [];
                        scope.seriesName = '';
                        scope.drillupText = '';
                        scope.originalCategoryData = [];
                        scope.otherCategoryData = [];
                        scope.currentSeriesDataObjects = {};
                        scope.tbcOptions = {};
                        scope.tbcChart;
                        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'),
                            noItemsFound: metLocalize('messages', 'noItemsFound'),
                            noItemsForFilters: metLocalize('messages', 'noItemsForFilters')
                        };

                        scope.tbcOptions = {
                            chart: {
                                type: 'pie',
                                renderTo: 'toolsByCategoryChartContainer',
                                width: 500,
                                height: 350,
                                events: {
                                    drillup: function() {
                                        updateChartSeries(scope.currentSeriesDataObjects);
                                    }
                                }
                            },
                            credits: {
                                enabled: false
                            },
                            legend: {
                                enabled: false
                            },
                            title: {
                                text: '',
                                y: 0
                            },
                            plotOptions: {
                                pie: {
                                    innerSize: 70,
                                    size: 230,
                                    depth: 45,
                                    showInLegend: false
                                },
                                series: {
                                    animation: {
                                        duration: 1000,
                                        easing: 'swing'
                                    }
                                }
                            },
                            series: [
                                {
                                    id: 'tbcData',
                                    name: '',
                                    data: scope.currentSeriesDataObjects,
                                    allowPointSelect: true,
                                    point: {
                                        events: {
                                            select: function() {
                                                scope.filterOnSelectedPoint(this);
                                                scope.updateFilterResults();
                                            }
                                        }
                                    }
                                }
                            ],
                            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.refreshChart = function(categoryFilterIds) {
                            scope.metStatsService.getToolsByCategory(categoryFilterIds,
                                function(response) {
                                    updateCategoryInfo(response);
                                    scope.categories = response.data;
                                    setChartOptions(response);
                                    metLocalize('commands', 'reset').promise.then(function(val) {
                                        scope.drillupText = val;
                                        updateHighchartsLangObject(scope.drillupText);
                                        if (!scope.tbcChart && scope.currentSeriesDataObjects.length > 0) {
                                            scope.tbcChart = new Highcharts.Chart(scope.tbcOptions);
                                        }
                                        if (scope.currentSeriesDataObjects.length > 0) {
                                            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;
                        }

                        scope.updateFilterResults = function() {
                            scope.$parent.updateResults();
                        };

                        scope.removeAllFilters = function() {
                            metInventoryFilters.removeAllFilters();
                            scope.updateResults();
                        };

                        scope.filterOnSelectedPoint = function(point) {
                            scope.removeAllFilters();
                            _.forEach(scope.categories,
                                function(category) {
                                    if (category.categoryId === point.id) {
                                        point.name = category.categoryName;
                                    }
                                });
                            metInventoryFilters.addSelectedFilter('category', point.id, point.name);
                        }

                        function setChartOptions(statsServiceResponse) {
                            scope.seriesName = scope.messages.numberOfTools.value;
                            scope.originalCategoryData = statsServiceResponse.data;
                            scope.currentSeriesDataObjects =
                                setInitialSeriesDataObjects(scope.originalCategoryData);
                            var seriesData = statsServiceResponse.seriesData.sort(function(a, b) {
                                return b[1] - a[1];
                            });
                            scope.tbcOptions.drilldown.series.length = 0;
                            getDrilldownSeries(scope.currentSeriesDataObjects, seriesData);
                            scope.tbcOptions.drilldown.series.push(
                                {
                                    "id": -2,
                                    "data": scope.otherCategoryData,
                                    "name": scope.seriesName,
                                    "selected": false,
                                    allowPointSelect: true,
                                    animation: false,
                                    point: {
                                        events: {
                                            select: function() {
                                                scope.filterOnSelectedPoint(this);
                                                scope.updateFilterResults();
                                                //-- the Highcharts drillUp method throws a known js error for this version (4.1.7)
                                                //-- the error was fixed in v.5
                                                this.series.chart.drillUp();
                                            }
                                        }
                                    }
                                }
                            );
                            scope.tbcOptions.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.tbcOptions.drilldown.series.push(retObj);
                                }
                            });
                        }

                        function setInitialSeriesDataObjects(categoryDataArray) {

                            var getDataLabel = function(categoryName) {
                                var charLimit = 15;
                                if (categoryName.length > charLimit) {
                                    var label = categoryName.substring(0, charLimit);
                                    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: 'tbcData',
                                name: scope.seriesName,
                                data: seriesArray
                            }
                            if (scope.tbcChart.get('tbcData')) {
                                var seriesData = scope.tbcChart.get('tbcData');
                                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.directive('metBulkUpdate', [
        '$http','$window','$filter', '$rootScope', 'urls', 'localize', 'inventoryGridConfig', 'inventoryFilters', 'itemFieldFactory', 'inventory', 'bulkInventoryService', 'notify', 'userItems',
        function ($http, $window, $filter, $rootScope, metUrls, metLocalize, metInventoryGrid, metInventoryFilters, metItemFields, metInventory, bulkInventoryService, notify, metUserItems) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryBulkUpdateHtml'),
                scope: {
                },
                link: function (scope, element, attrs) {
                    scope.gridConfig = metInventoryGrid;
                    scope.isUpdating = false;
                    scope.showTransfer = false;
                    scope.trades = metItemFields.trades;
                    scope.people = metItemFields.people;
                    scope.locations = metItemFields.locations;
                    scope.messages = {
                        itemsSelected: metLocalize('messages', 'inventoryItemsSelected'),
                        edit: metLocalize('commands', 'edit'),
                        delete: metLocalize('commands', 'delete'),
                        deselectAll: metLocalize('messages', 'deselectAll'),
                        deleteItems: metLocalize('messages', 'ConfirmDeleteSelected'),
                        invalidRequest: metLocalize('messages', 'invalidRequest')
                    }

                    scope.transferClicked = function () {
                        scope.showTransfer = !scope.showTransfer;
                    }

                    scope.updateOptions = [
                        { id: "category", name: metLocalize('fieldNames', 'categoryId'), items: metItemFields.categories, idProperty:"categoryId", nameProperty:"categoryName" },
                        { id: "place", name: metLocalize('fieldNames', 'placeId'), items: scope.locations, idProperty: "placeId", nameProperty: "placeName" },
                        { id: "person", name: metLocalize('fieldNames', 'personId'), items: scope.people, idProperty: "personId", nameProperty: "personName" },
                        { id: "division", name: metLocalize('fieldNames', 'divisionId'), items: scope.trades, idProperty: "divisionId", nameProperty: "divisionName" },
                        { id: "status", name: metLocalize('fieldNames', 'status'), items: metItemFields.statuses, idProperty: "statusId", nameProperty: "statusName" }
                    ]

                    $rootScope.$on("list-updated", function (event, args) {
                        switch (args.name) {
                            case "place":
                                scope.locations = args.items;
                                break;
                            case "division":
                                scope.trades = args.items;
                                break;
                            case "person":
                                scope.people = args.items;
                                break;
                        }

                        var filter = $filter('filter')(scope.updateOptions, { id: args.name })[0];
                        if (filter) {
                            filter.items = args.items;
                        }
                    });

                    function createBulkUpdateRequest(option, item) {
                        var request = {
                            userItemIds: metInventoryGrid.selectedItemIds,
                            updateAllUserItems: false, // removing the feature to update all and only ever update whats selected on screen
                            groupIds: null, // whithout update all we need to send in null for groupIds
                            groupType: 0, // whithout update all we need to send in 0 for grouping
                            filters: metInventoryFilters.searchRequest
                        }

                        var id = item[option.idProperty];
                        switch (option.id) {
                            case "category":
                                request.userCategoryId = id;
                                break;
                            case "place":
                                request.placeId = id;
                                request.userLocationId = id;
                                break;
                            case "person":
                                request.userPersonId = id;
                                break;
                            case "division":
                                request.userDivisionId = id;
                                break;
                            case "status":
                                request.itemStatus = id;
                                break;
                        }
                        return request;
                    }


                    scope.update = function (option, item) {
                        scope.isUpdating = true;
                        var request = createBulkUpdateRequest(option, item);
                        bulkInventoryService.update(request)
                            .then(function (result) {
                                if (result.isValid) {
                                    if (request.placeId) {
                                        metUserItems.search(metInventoryFilters.searchRequest,
                                            function(response) {
                                                var isPaging = metInventoryFilters.searchRequest.skip === 0;
                                                metInventoryFilters.updateAvailableFilters(response.availableFilters,
                                                    isPaging);
                                                metInventoryGrid.gridUpdated(response);
                                                scope.loading = false;
                                                scope.noInventory = metInventoryGrid.totalResults === 0;
                                                if (scope.userItemId > 0) {
                                                    _.forEach(scope.loadedGroups,
                                                        function(group) {
                                                            _.forEach(group.items,
                                                                function(itemLine) {
                                                                    itemLine.isExpanded = true;
                                                                });
                                                        });
                                                }
                                            });
                                    } else {
                                        metInventoryGrid.bulkUpdateGridProperties(option.idProperty, item.statusId);
                                        metInventoryGrid.bulkUpdateGridProperties(option.id, item[option.nameProperty]);
                                    }
                                }
                                else {
                                    notify.error(scope.messages.invalidRequest);
                                }
                                scope.isUpdating = false;
                            })
                            .finally(function(){
                                bulkInventoryService.refreshInventoryGrid();
                            });
                        
                    }

                    scope.deleteSelectedItems = function (item) {
                        scope.isUpdating = true;
                        var UserItemIds = { UserItemIds: metInventoryGrid.selectedItemIds };
                            $http({
                                url: metUrls('userItemsApi').concat('/bulk'),
                                method: 'DELETE',
                                data: UserItemIds,
                                headers: {
                                    "Content-Type": "application/json;charset=utf-8"
                                }
                            }).then(function (res) {
                                $window.location.href = metUrls('inventory');
                            }, function (error) {
                                console.log(error);
                                scope.isUpdating = false;
                            });
                    };

                    scope.deselectAll = function () {
                        metInventoryGrid.allItemsSelected = false;
                        metInventoryGrid.selectAll();
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.controller('inventoryController', [
        '$state', '$http', '$q', '$stateParams', '$filter', '$scope', 'featureToggle', 'itemFieldFactory', 'inventoryFilters', '$modal', 'modalOptionsService', 'urls', 'localize', '$window', 'userItems', 'host', 'stats', 'dates', 'notify', 'authService',
        function inventoryCtrl($state, $http, $q, $stateParams, $filter, $scope, featureToggle, metItemFieldFactory, metInventoryFilters, $modal, modalOptionsService, metUrls, metLocalize, $window, metUserItems, host, metStats, metDates, notify, authService) {

            $scope.filtersExpanded = false;
            $scope.categoriesExpanded = false;
            $scope.initialize = initialize;
            $scope.loading = true;
            $scope.inventoryFilters = metInventoryFilters;
            $scope.exportLink = '';
            $scope.mostRecentTransfers = [];
            $scope.statCounts = {};
            $scope.dashboardIsOpen = false;
            $scope.dateFormat = metDates.date(true);
            $scope.dateTimeFormat = metDates.shortDateTime(true);
            $scope.filteredTransfers = false;
            $scope.dashboardElement = $('.summary-dashboard-wrapper')[0];
            $scope.updateResults = updateResults;
            $scope.selectedFilters = metInventoryFilters.selectedFilters;
            $scope.exportUserInventory = exportUserInventory;
            $scope.noInventory;
            $scope.toggleSearchContainer = toggleSearchContainer;
            $scope.clearSearch = clearSearch;
            $scope.download = download;

            $scope.showHideFilters = function (forceClose) {
                if (forceClose) {
                    $scope.filtersExpanded = false;
                    $scope.styleMoreFiltersList(false);

                } else {
                    $scope.showHideCategories(true);
                    $scope.filtersExpanded = !$scope.filtersExpanded;
                    if ($scope.filtersExpanded) {
                        $scope.styleMoreFiltersList(true);
                    } else {
                        $scope.styleMoreFiltersList(false);
                    }
                }

                if (!$scope.filtersExpanded) {
                    metInventoryFilters.closeAllFilters();
                }
            }
            

            $scope.messages = {
                viewTransferHistoryConversational: metLocalize('commands', 'viewTransferHistoryConversational'),
                mostRecentTransfers: metLocalize('fieldNames', 'mostRecentTransfers'),
                emptyTransfersText: metLocalize('messages', 'emptyTransfersText'),
                noTransfersFound: metLocalize('messages', 'noTransfersFound'),
                noTransfersForFilter: metLocalize('messages', 'noTransfersForFilter'),
                getASnapshot: metLocalize('commands', 'getASnapshot'),
                unspecified: metLocalize('titles', 'unassigned'),
                itemsOn: metLocalize('fieldNames', 'itemsOn'),
                noRecentTransfers: metLocalize('messages', 'noRecentTransfers'),
                totalPeople: metLocalize('messages', 'totalPeople'),
                viewInPeople: metLocalize('messages', 'viewInPeople'),
                totalPlaces: metLocalize('messages', 'totalPlaces'),
                viewInPlaces: metLocalize('messages', 'viewInPlaces'),
                divisions: metLocalize('messages', 'divisions'),
                viewInDivisions: metLocalize('messages', 'viewInDivisions'),
                hideDashboard: metLocalize('commands', 'hideDashboard'),
                viewDashboard: metLocalize('commands', 'viewDashboard'),
                inventoryDashboard: metLocalize('titles', 'inventoryDashboard'),
                inventoryOverTime: metLocalize('titles', 'inventoryOverTime'),
                createATransfer: metLocalize('commands', 'createATransfer'),
                totalTools: metLocalize('fieldNames', 'totalTools'),
                whatsNew: metLocalize('messages', 'whatsNew'),
                wereAddingNewFeatures: metLocalize('messages', 'wereAddingNewFeatures'),
                placeForEverything: metLocalize('messages', 'placeForEverything'),
                everythingInItsPlace: metLocalize('messages', 'everythingInItsPlace'),
                getTheDownload: metLocalize('messages', 'getTheDownload'),
                introducingPlaces: metLocalize('messages', 'introducingPlaces'),
                updatedTransfers: metLocalize('messages', 'updatedTransfers'),
                needDownload: metLocalize('messages', 'needDownload'),
                dismiss: metLocalize('commands', 'dismiss')
            };

            $scope.styleMoreFiltersList = function (open) {
                var tableContainer = document.getElementById('tableContainer');
                var filterListContainer = document.getElementById('filterList');
                var filterContainer = document.getElementById('filter-container');
                var slideDownHeader = document.getElementsByClassName('slideDown-header')[0];
                var tableDiv = document.getElementById('inventory-grid');

                if (open) {
                    if (isTrident() || isEdge()) {
                        filterListContainer.style.position = 'absolute';
                        filterListContainer.style.top = '0';
                        filterListContainer.style.left = '0';
                        filterListContainer.style.zIndex = '2000';
                        filterContainer.style.boxShadow = '1px 5px 7px 0 rgba(0, 0, 0, 0.6)';
                        slideDownHeader.style.boxShadow = '1px 5px 7px 0 rgba(0, 0, 0, 0.6)';
                    }
                    else {
                        tableContainer.style.display = 'flex';
                        tableContainer.style.flexFlow = 'row nowrap';
                        tableContainer.style.justifyContent = 'space-between';
                        tableContainer.style.alignItems = 'flex-start';
                        tableDiv.style.width = '100%';
                    }
                }
                else {
                    filterListContainer.style.display = 'none';
                    tableContainer.style.display = 'unset';
                    tableDiv.style.width = '100%';
                }
            }

            function isTrident() {
                //-- Trident is the engine for IE11
                var re = new RegExp('trident', 'i');
                return re.test(navigator.userAgent.toString());
            }

            function isEdge() {
                var re = new RegExp('edge\/', 'i');
                return re.test(navigator.userAgent.toString());
            }

            $scope.searchKeyUp = function ($event) {
                if ($event.keyCode === 13) {
                    $scope.updateResults(false);
                }
            };

            $scope.showHideCategories = function (forceClose) {
                if (forceClose) {
                    $scope.categoriesExpanded = false;
                } else {
                    $scope.showHideFilters(true);
                    $scope.categoriesExpanded = !$scope.categoriesExpanded;
                }
            };

            $scope.showHideDashboard = function () {
                $scope.dashboardIsOpen = !$scope.dashboardIsOpen;
                localStorage.setItem('dashboard', $scope.dashboardIsOpen);
            };

            function setDashboardInitState(isShown) {
                var elDashboard = $('.summary-dashboard-wrapper')[0];
                if (isShown || isShown === null) {
                    $scope.dashboardIsOpen = true;

                    if (elDashboard) {
                        elDashboard.style.display = 'flex';
                    }
                }
                else {
                    elDashboard.style.display = 'none';
                }
            }

            $scope.tickUrl = null;
            switch (host.getCurrentHost()) {
                case 'com':
                    $scope.tickUrl = 'https://www.milwaukeetool.com/power-tools/cordless/48-21-2000';
                    break;
                case 'au':
                    $scope.tickUrl = 'https://www.milwaukeetools.com.au/power-tools/cordless/onet-1 ';
                    break;
                case 'nz':
                    $scope.tickUrl = 'https://www.milwaukeetools.co.nz/power-tools/cordless/onet-1';
                    break;
                case 'eu':
                    $scope.tickUrl = 'https://www.milwaukeetool.eu/milwaukee-tick-bluetooth-tracking-module/btm-eu/';
                    break;
                default:
                    $scope.tickUrl = 'https://www.milwaukeetool.com/power-tools/cordless/48-21-2000';
                    break;
            }

            var that = this;

            function updateResults(isPaging) {
                var timeoutPeriod = 0;
                if ($scope.filtersExpanded) {
                    $scope.showHideFilters(true);
                    timeoutPeriod = 500;
                } else if ($scope.categoriesExpanded) {
                    $scope.showHideCategories(true);
                    timeoutPeriod = 500;
                }
                setTimeout(function () {
                    that.refreshGrid(isPaging);
                }, timeoutPeriod);
            }

            $scope.getHref = function (url) {
                var dateFormat = $scope.dateFormat;
                var offset = moment().utcOffset();
                var queryParam = '?offset=' + offset + '&format=' + dateFormat;
                $scope.exportLink = url + queryParam;
            };

            metItemFieldFactory.init();
            //if (authService.isAuthenticated()) {
            //    metItemFieldFactory.init(); 
            //}
            

            $scope.loadMostRecentTransfers = function (filtersForTransfersDashboard) {
                if (filtersForTransfersDashboard !== undefined && filtersForTransfersDashboard !== null) {
                    metStats.getTransfersByFilters(filtersForTransfersDashboard, function (data) {
                        $scope.mostRecentTransfers = data;
                        $scope.filteredTransfers = true;
                        for (var i = 0; i < $scope.mostRecentTransfers.length; i++) {
                            if ($scope.mostRecentTransfers[i].fromLocationName === null) {
                                $scope.mostRecentTransfers[i].fromLocationName = $scope.messages.unspecified.value;
                            }
                            if ($scope.mostRecentTransfers[i].toLocationName === null) {
                                $scope.mostRecentTransfers[i].toLocationName = $scope.unspecified.value;
                            }
                            if ($scope.mostRecentTransfers[i].fromPlaceNames && $scope.mostRecentTransfers[i].fromPlaceNames.length > 0) {
                                $scope.mostRecentTransfers[i].fromLocationName = $scope.mostRecentTransfers[i].fromPlaceNames.join(', ');
                            } else {
                                $scope.mostRecentTransfers[i].fromPlaces = $scope.mostRecentTransfers[i].fromLocationName;
                            }
                            var transferTos = [];
                            if ($scope.mostRecentTransfers[i].toLocationName) {
                                transferTos.push($scope.mostRecentTransfers[i].toLocationName);
                            }
                            if ($scope.mostRecentTransfers[i].toPersonName) {
                                transferTos.push($scope.mostRecentTransfers[i].toPersonName);
                            }
                            if ($scope.mostRecentTransfers[i].toDivisionName) {
                                transferTos.push($scope.mostRecentTransfers[i].toDivisionName);
                            }
                            if ($scope.mostRecentTransfers[i].toStatusName) {
                                transferTos.push($scope.mostRecentTransfers[i].toStatusName);
                            }
                            $scope.mostRecentTransfers[i].toLocationName = transferTos.join(', ');
                        $scope.mostRecentTransfers[i].transferredOnLocal = metDates.convertUtcToLocal($scope.mostRecentTransfers[i].transferredOn);
                        }
                    });
                }
            };

            $scope.updatedGridByFilters = [];
            $scope.filtersForStatsDashboard = { placeIds: [], personIds: [], divisionIds: [] };
            $scope.totalToolsCount = 0;



            $scope.$on('grid-updated',
                function (event, args) {
                    $scope.totalToolsCount = args.totalResults;

                    enableOrDisable($scope.totalToolsCount);
                    if (args.availableFilters !== undefined && args.availableFilters !== null) {
                        $scope.updateStatCounts(args.availableFilters);
                    } else {
                        $scope.statCounts = {
                            placesCount: 0,
                            personCount: 0,
                            divisionCount: 0
                        };
                    }
                    setTimeout(function () {
                        var categorySelected = _.find($scope.selectedFilters, function (filter) {
                            return filter.filterName === 'category';
                        });
                        if (categorySelected === undefined || categorySelected === null) {
                            that.refreshChart();
                        } else {
                            that.refreshChart(args.availableFilters.categoryIds);
                        }
                            setDashboardInitState(JSON.parse(localStorage.getItem('dashboard')));
                        },
                        500);
                });

            $scope.updateStatCounts = function (filterIds) {
                $scope.statCounts = {
                    placesCount: filterIds.placeIds.indexOf(-1) > -1 ? filterIds.placeIds.length - 1 : filterIds.placeIds.length,
                    personCount: filterIds.personIds.indexOf(-1) > -1 ? filterIds.personIds.length - 1 : filterIds.personIds.length,
                    divisionCount: filterIds.tradeIds.indexOf(-1) > -1 ? filterIds.tradeIds.length - 1 : filterIds.tradeIds.length
                };
            };

            $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.$on('transferComplete', function () {
                $scope.loadMostRecentTransfers();
            });

            $scope.$on('updated-Results', function (event, filtersForTransfersDashboard) {
                if (filtersForTransfersDashboard !== undefined && filtersForTransfersDashboard !== null) {
                    $scope.loadMostRecentTransfers(filtersForTransfersDashboard);
                }
            });

            $scope.region = "";
            
            function exportUserInventory() {
                if ($scope.totalToolsCount === 0) {
                    return;
                }
                var dateFormat = $scope.dateFormat;
                var offset = moment().utcOffset();

                var filters = JSON.stringify($scope.inventoryFilters.searchRequest);
                var url = metUrls('apiBulkOperations').concat('/export?offset=' + offset + '&format=' + dateFormat + '&filters=' + filters);
                $http.get(url, { responseType: 'arraybuffer' })
                    .then(function (response) {
                        download(response);
                    });
            }

            function enableOrDisable(toolCount) {
                var report = $('#excelReportLink');
                if (toolCount === 0) {
                    report.addClass('met-disabled');
                }
                if (toolCount !== 0 && report.hasClass('met-disabled')) {
                    report.removeClass('met-disabled');
                }
            }

            function download (response) {
                var disposition = response.headers('Content-Disposition');
                if (!disposition) {
                    disposition = 'attachment; filename="MilwaukeeTool-OneKey-Inventory-Export.xlsx"';
                }
                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 = document.createElement('a');
                    downloadLink.href = objectUrl;
                    downloadLink.download = fileName;
                    document.body.appendChild(downloadLink);
                    downloadLink.click();
                }
            }

            function clearSearch() {
                $scope.inventoryFilters.searchTerm = "";
                $scope.updateResults(false);
                toggleSearchContainer(true);
            }


            function toggleSearchContainer(close) {
                if (!$scope.searchContainer) {
                    $scope.searchContainer = document.getElementById('search-container');
                    $scope.searchCloseButton = document.getElementById('close-expansion-box-icon');
                    $scope.placesSearchInput = document.getElementById('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(region, message){
                $scope.region = region;
                $scope.transferFrom = localStorage.getItem('transferFrom');
                $state.go('inventory', { success: $stateParams.success, clearFilters: $stateParams.clearFilters });
                if ($stateParams.success) {
                    notify.itemAdded(message);
                }
                $scope.inventoryFilters.tickOnly = false;
                $scope.inventoryFilters.oneKeyOnly = false;
                if ($stateParams.clearFilters) {
                    for (var i = $scope.selectedFilters.length; i >= 0; i--) {
                        $scope.selectedFilters.pop();
                    }
                    localStorage.removeItem('selectedFilters');
                }               
            }
        }
    ]);
}());

(function (module) {
    'use strict';

    module.filter('rawHtml', ['$sce', function ($sce) {
        return function (val) {
            return $sce.trustAsHtml(val);
        };
    }]);

}(angular.module('oneKeyApp')));

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.filter("append", function () {
        return function (array, addOption) {
            if (!angular.isArray(array)) {
                return array;
            }
            if (!addOption) {
                return array;
            }

            return [addOption].concat(array);
        };
    });
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metAddLocation', [
        '$compile', '$parse', '$timeout', '$templateCache', 'localize', 'focus', 'locations',
        function ($compile, $parse, $timeout, $templateCache, metLocalize, metFocus, metLocations) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: '/OneKeyScripts/app/directives/locations/locationsAdd.html',
                scope: { },
                link: function (scope, element, attrs, ctrl) {
                    scope.messages = {
                        addLocation: metLocalize('titles', 'addLocation'),
                        cancel: metLocalize('commands', 'cancel'),
                        save: metLocalize('commands', 'save'),
                        locationTitle: metLocalize('fieldNames', 'locationName'),
                        jobNumber: metLocalize('fieldNames', 'JobNumber'),
                        error: metLocalize('messages', 'locationAlreadyExists'),
                        required: metLocalize('validation', 'requiredError'),
                        placeExistsError: metLocalize('messages', 'placeNameAlreadyExists')
                    }

                    scope.stuff = 'junk';
                    scope.saving = false;
                    scope.valid = true;
                    scope.duplicate = false;

                    scope.clearError = function () {
                        scope.duplicate = false;
                    }

                    scope.save = function () {
                        scope.saving = true;
                        metLocations.create(scope.location, function (newLocation) {
                            scope.$emit('locationAdded', { location: newLocation });
                        }, function (error) {
                            scope.saving = false;
                            scope.valid = false;
                            if (scope.location.locationName == "" || scope.location.locationName == undefined) {
                                scope.duplicate = true;
                                scope.error = scope.messages.required.value;
                            }
                            else {
                                scope.duplicate = true;
                                scope.error = scope.messages.placeExistsError.value;
                            } 
                        });
                    }

                    scope.cancel = function () {
                        scope.$emit('clearLocation', {});
                    }

                    $timeout(function () { metFocus('loaded'); }, 100);
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metLocationSelector', [
        '$compile', '$parse', '$modal', '$templateCache', 'localize', 'urls', 'modalOptionsService', 'locations',
        function ($compile, $parse, $modal, $templateCache, metLocalize, metUrls, modalOptionsService, metLocations) {
            return {
                restrict: 'E',
                replace: true,
                require: 'ngModel',
                template:
                    '<div><select class="form-control" name="{{name}}" id="{{name}}" tabindex="{{tabindex}}"' +
                    ' ng-model="myModel" data-ng-options="loc.placeName for loc in locations | append:addOption | orderBy:\'placeName\' track by loc.placeId" ' +
                    ' data-ng-disabled="metDisabled" data-ng-change="metResolveToPopup && (myModel == addOption) ? openModal() : changeLocation()" data-met-select-placeholder="" ' +
                    ' data-met-focus-on="{{metFocusOn}}" data-met-focus-on-if="metFocusOnIf()" met-resolve-to-popup="metResolveToPopup">  ' +
                    '</select></div>',
                scope: {
                    locations: '=metLocations',
                    myModel: '=ngModel',
                    name: '@',
                    tabindex: '@metTabindex',
                    onLocationAdded: '&metOnLocationAdded',
                    excludeAddOption: '@metExcludeAddOption',
                    includePlaceholder: '@metIncludePlaceholder',
                    metFocusOn: '@',
                    metFocusOnIf: '&',
                    metDisabled: '=?',
                    metResolveToPopup: '=?'
                },
                link: function (scope, element, attrs, ctrl) {
                    
                    var previousValue = scope.myModel;
                    scope.openModal = openModal;

                    scope.messages = {
                        selectFromList: metLocalize('commands', 'selectFromList'),
                        addLocation: metLocalize('commands', 'addLocationOption'),
                        addPlaceOption: metLocalize('commands','addPlaceOption')
                    };

                    if (!scope.excludeAddOption) {
                        scope.addOption = { placeId: -100, placeName: '' };
                        metLocalize('commands', 'addPlaceOption').promise.then(function(val) {
                            scope.addOption = { placeId: -100, placeName: val };
                        });
                    }

                    if (scope.myModel === undefined || scope.myModel.placeId < 0) {
                        scope.myModel = { placeId: -1 };
                    }

                    previousValue = scope.myModel;
                    scope.changeLocation = function () {
                        if (scope.myModel === scope.addOption) {
                            var container = getContainer();
                            var el = $compile('<met-add-location></met-add-location>')(scope);
                            container.append(el);
                            showAddDialog(container);
                        } else {
                            previousValue = scope.myModel;
                        }
                    };

                    scope.$on('locationAdded', function (event, data) {
                        scope.myModel = data.location;
                        var container = getContainer();
                        scope.onLocationAdded();
                        hideAddDialog(container);
                    });

                    scope.$on('clearLocation', function (event, data) {
                        var container = getContainer();
                        ctrl.$setViewValue(previousValue);
                        hideAddDialog(container);
                    });

                    function showAddDialog(container) {
                        container.children().css('display', 'none');
                        $('#onekey-add-object-dialog').css('display', 'inline');
                    }

                    function hideAddDialog(container) {
                        container.children().css('display', 'inline-block');
                        $('#onekey-add-object-dialog').remove();
                    }

                    function getContainer() {
                        return element.parents('.add-new-item-container');
                    }

                    function openModal () {
                        var modalOptions = {
                            templateUrl: metUrls('addLocationModal'),
                            backdrop: true,
                            keyboard: true,
                            modalFade: true,
                            controller: function ($scope, $modalInstance, modalOptionsService) {
                                $scope.modalInit = modalInit;
                                $scope.save = save;
                                $scope.cancel = cancel;
                                
                                function save() {
                                    var locationModel = { placeName: $scope.addLocationForm.location.$modelValue, typeId: 1 };
                                    $scope.saving = true;
                                    metLocations.create(locationModel, function (newLocation) {
                                        $scope.$emit('locationAdded', { location: newLocation });
                                        $modalInstance.close(newLocation);
                                    }, function (error) {
                                        $scope.saving = false;
                                        $scope.valid = false;
                                        if ($scope.location.placeName === "" || $scope.location.placeName === undefined) {
                                            $scope.duplicate = true;
                                            $scope.error = $scope.modalMessages.required.value;
                                        }
                                        else {
                                            $scope.duplicate = true;
                                            $scope.error = $scope.modalMessages.placeExistsError.value;
                                        }
                                    });
                                }

                                function cancel(reason) {
                                    $modalInstance.dismiss(reason);
                                }

                                function handleError(error) {
                                    $scope.saving = false;
                                    $scope.valid = false;
                                    $scope.duplicate = true;
                                    $scope.error = error.data.message === undefined ? error.data : error.data.message;
                                }

                                function modalInit() {
                                    $scope.modalMessages = modalOptionsService.locationModalOptions.messages;
                                }
                            },
                        };
                        var modalInstance = $modal.open(modalOptions);

                        modalInstance.result.then(function (response) {
                            scope.locations.push(response.toJSON());
                            scope.myModel = response.toJSON();
                            ctrl.$setViewValue(scope.myModel);

                        }, function(error){
                            ctrl.$setViewValue(previousValue);
                            scope.error = error;
                        });
                    }


                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.service('searches', ['$resource', 'urls', function ($resource, metUrls) {
		var resource = metUrls('searchApi');
	    var searchResource = $resource(metUrls('userItemsApi').concat('/search?searchTerm=:searchTerm&take=1000'),
		    { searchTerm: '@searchTerm' },
		    {
			    'search': { method: 'GET' }
			});		

        var resultType = {
            inventory: 1,
            locations: 2,
            manufacturers: 3,
            categories: 4,
            none: -1
        };

        var empty = '';

		return {
			searchAll: function(searchTerm, callback) {
				return searchResource.search(searchTerm, callback);
			},
            typeaheadDataSourceFactory: function (flag) {
                return new Bloodhound({
                    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
                    queryTokenizer: Bloodhound.tokenizers.whitespace,
                    remote: {
                        cache: false,
                        url: resource + '?value=%QUERY',
                        wildcard: '%QUERY',
                        filter: function (response) {
                            var items = response.results;
                            if (flag == resultType.none) {
                                if (items.length == 0) {
                                    return [];
                                } else {
                                    return [{ name: empty }];
                                }
                            }

                            var data = new Array();
                            for (var i = 0; i < items.length; ++i) {
                                var item = items[i];
                                if (item.resultType == flag) {
                                    data.push(item);
                                }
                            }

                            return data;
                        }
                    }
                });
            },
            resultType: resultType,
            goTo: function (item) {
                if (!item) {
                    return empty;
                }

                var url = empty;
                switch (item.resultType)
                {
                    case resultType.inventory:
                        url = metUrls('inventory');
                        break;
                    case resultType.locations:
                        url = metUrls('locations');
                        break;
                    case resultType.manufacturers:
                        url = metUrls('manufacturers');
                        break;
                    case resultType.categories:
                        url = metUrls('categories');
                        break;
                }

                if (url != empty) {
                    url = url.concat('/', item.id);
                }

                return url;
            }
        };
    }]);
}());
(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metAddCategory', [
        '$compile', '$parse', '$timeout', '$templateCache', 'localize', 'focus', 'categories',
        function ($compile, $parse, $timeout, $templateCache, metLocalize, metFocus, metCategories) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: '/OneKeyScripts/app/directives/categories/categoriesAdd.html',
                scope: {},
                link: function (scope, element, attrs, ctrl) {
                    scope.messages = {
                        addCategory: metLocalize('titles', 'addCategory'),
                        cancel: metLocalize('commands', 'cancel'),
                        save: metLocalize('commands', 'save'),
                        categoryTitle: metLocalize('fieldNames', 'categoryName'),
                        parentCategoryTitle: metLocalize('fieldNames', 'parentCategoryName'),
                        required: metLocalize('validation', 'requiredError')
                    }

                    scope.stuff = 'junk';
                    scope.saving = false;
                    scope.valid = true;
                    scope.categories = [];
                    scope.category = {
                        categoryName: ''
                    };
                    scope.duplicate = false;

                    scope.clearError = function () {
                        scope.duplicate = false;
                    }

                    metCategories.getAll(
                    {
                        includeUncategorized: false
                    },
                    function (data) {
                        _.forEach(data.items, function (category) {
                            scope.categories.push(category);
                        });
                    });

                    scope.save = function () {
                        scope.saving = true;
                        if (scope.category.parentCategory) {
                            scope.category.parentCategoryId = scope.category.parentCategory.categoryId;
                        }

                        metCategories.create(scope.category, function (newCategory) {
                            scope.$emit('categoryAdded', { category: newCategory });
                        }, function (error) {
                            scope.saving = false;
                            scope.valid = false;
                            if (scope.category.categoryName == "" || scope.category.categoryName == undefined) {
                                scope.duplicate = true;
                                scope.error = error.data.message;
                            }
                            else {
                                scope.duplicate = true;
                                scope.error = error.data.message;
                            }
                            
                            setTimeout(function () { scope.$apply(); }, 10);
                        });
                    }

                    scope.cancel = function () {
                        scope.$emit('clearCategory', {});
                    }

                    $timeout(function () { metFocus('loaded'); }, 100);
                }
            };
        }
    ]);
}());

    (function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metCategorySelector', [
        '$compile', '$parse', '$modal', 'localize', 'urls', 'modalOptionsService',
        function ($compile, $parse, $modal, metLocalize, metUrls, modalOptionsService) {
            return {
                restrict: 'E',
                replace: true,
                require: 'ngModel',
                template:
    '<div><select class="form-control" name="{{ name }}" id="{{ name }}" tabindex="{{ tabindex }}"' +
    ' ng-model="myModel" data-ng-options="cat.categoryName for cat in categories | append:addOption track by cat.categoryId" ' +
    ' data-ng-disabled="categories.length == 0 || metDisabled" data-ng-change="(metResolveToPopup && (myModel == addOption)) ? openModal() : changeCategory()" ' +
    ' data-met-select-placeholder="" data-met-focus-on="{{ metFocusOn }}" data-met-focus-on-if="metFocusOnIf()" ' + 
    ' met-resolve-to-popup="metResolveToPopup === undefined ? false : metResolveToPopup">' +
    '</select></div>',
                scope: {
                    categories: '=metCategories',
                    myModel: '=ngModel',
                    name: '@',
                    tabindex: '@metTabindex',
                    onCategoryAdded: '&metOnCategoryAdded',
                    excludeAddOption: '@metExcludeAddOption',
                    includePlaceholder: '@metIncludePlaceholder',
                    metFocusOn: '@',
                    metFocusOnIf: '&',
                    metDisabled: '=?',
                    metResolveToPopup: '=?'
                },
                link: function (scope, element, attrs, ctrl) {
                    
                    scope.messages = {
                        selectFromList: metLocalize('commands', 'selectFromList'),
                        addCategory: metLocalize('commands', 'addCategoryOption'),
                        parentCategoryTitle: metLocalize('fieldNames', 'parentCategoryName')
                    };

                    scope.openModal = openModal;
                    //scope.category = {};
                    if (!scope.excludeAddOption) {
                        scope.addOption = { categoryId: -100 };
                        metLocalize('commands', 'addCategoryOption').promise.then(function (val) {
                            scope.addOption = { categoryId: -100, categoryName: val };
                        });
                    }

                    if (scope.myModel === undefined ||scope.myModel.categoryId === undefined || scope.myModel.categoryId < 0) {
                        scope.myModel = { categoryId: -1 };
                    }

                    var previousValue = scope.myModel;
                    if (!previousValue) {
                        previousValue = { categoryId: -1 };
                    }

                    scope.changeCategory = function () {
                        if (scope.myModel.categoryId === scope.addOption.categoryId) {
                            var container = getContainer();
                            var el = $compile('<met-add-category></met-add-category>')(scope);
                            container.append(el);
                            showAddDialog(container);
                        } else {
                            previousValue = scope.myModel;
                        }
                    };

                    scope.$on('categoryAdded', function (event, data) {
                        scope.myModel = data.category;
                        var container = getContainer();
                        scope.onCategoryAdded();
                        hideAddDialog(container);
                    });

                    scope.$on('clearCategory', function (event, data) {
                        var container = getContainer();
                        ctrl.$setViewValue(scope.previousValue);
                        hideAddDialog(container);
                    });
                    
                    function showAddDialog(container) {
                        container.children().css('display', 'none');
                        $('#onekey-add-object-dialog').css('display', 'table-cell');
                    }

                    function hideAddDialog(container) {
                        container.children().css('display', 'block');
                        $('#onekey-add-object-dialog').remove();
                    }

                    function getContainer() {
                        return element.parents('.add-new-item-container');
                    }

                    function openModal () {
                        var modalOptions = modalOptionsService.sharedDefaultOptions;
                        modalOptions.templateUrl = metUrls('addCategoryModal');
                        var modalInstance = $modal.open(modalOptions);

                        modalInstance.result.then(function(result){
                            scope.myModel = result.toJSON();
                        }, function(reason){
                            scope.myModel = previousValue;
                            scope.error = reason;
                        });
                    }

                    function init() {
                        if (!angular.isDefined(scope.myModel)) {
                            scope.myModel = { categoryId: -1 };
                        }
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metAddPerson', [
        '$compile', '$parse', '$timeout', '$templateCache', 'localize', 'focus', 'people',
        function ($compile, $parse, $timeout, $templateCache, metLocalize, metFocus, metPeople) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: '/OneKeyScripts/app/directives/persons/peopleAdd.html',
                scope: {},            

                link: function (scope, element, attrs, ctrl) {
                    scope.person = {
                        personName:''
                        };

                    scope.messages = {
                        addPerson: metLocalize('titles', 'addPerson'),
                        cancel: metLocalize('commands', 'cancel'),
                        save: metLocalize('commands', 'save'),
                        personTitle: metLocalize('fieldNames', 'personName'),
                        required: metLocalize('validation', 'requiredError')
                    }

                    scope.stuff = 'junk';
                    scope.saving = false;
                    scope.valid = true;
                    scope.duplicate = false;

                    scope.clearError = function () {
                        scope.duplicate = false;
                    }

                    scope.save = function () {
                        scope.saving = true;
                        metPeople.create(scope.person, function (newPerson) {
                            scope.$emit('personAdded', { person: newPerson });
                        }, function (error) {
                            scope.saving = false;
                            scope.valid = false;
                            if (scope.person.personName == "" || scope.person.personName == undefined) {
                                scope.duplicate = true;
                                scope.error = error.data.message;
                            }
                            else {
                                scope.duplicate = true;
                                scope.error = error.data.message;
                            }
                            
                        });
                    }

                    scope.cancel = function () {
                        scope.$emit('clearPerson', {});
                    }

                    $timeout(function () { metFocus('loaded'); }, 100);
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metPersonSelector', [
        '$compile', '$parse', '$modal', 'localize', 'urls', 'modalOptionsService', 'people',
        function ($compile, $parse, $modal, metLocalize, metUrls, modalOptionsService, metPeople) {
            return {
                restrict: 'E',
                replace: true,
                require: 'ngModel',
                template:
    '<div><select class="form-control" name="{{ name }}" id="{{ name }}" tabindex="{{ tabindex }}"' +
    ' ng-model="myModel" data-ng-options="person.personName for person in people | append:addOption | orderBy: \'personName\' track by person.personId" ' +
    ' data-ng-disabled="person.length == 0 || metDisabled" data-ng-change="metResolveToPopup && (myModel == addOption) ? openModal() : changePerson()" ' +
    ' data-met-select-placeholder="" data-met-focus-on="{{ metFocusOn }}" data-met-focus-on-if="metFocusOnIf()"> met-resolve-to-popup="metResolveToPopup" ' +
    '</select></div>',
                scope: {
                    people: '=metPeople',
                    myModel: '=ngModel',
                    name: '@',
                    tabindex: '@metTabindex',
                    onPersonAdded: '&metOnPersonAdded',
                    excludeAddOption: '@metExcludeAddOption',
                    includePlaceholder: '@metIncludePlaceholder',
                    metFocusOn: '@',
                    metFocusOnIf: '&',
                    metDisabled: '=?',
                    metResolveToPopup: '=?'
                },
                link: function (scope, element, attrs, ctrl) {
                    scope.openModal = openModal;
                    scope.messages = {
                        selectFromList: metLocalize('commands', 'selectFromList'),
                        addPerson: metLocalize('commands', 'addPersonOption')
                    };

                    if (scope.myModel === undefined || scope.myModel.personId < 0) {
                        scope.myModel = { personId: -1 };
                    }

                    if (!scope.excludeAddOption) {
                        scope.addOption = { personId: -100, personName: '' };
                        metLocalize('commands', 'addPersonOption').promise.then(function (val) {
                            scope.addOption = { personId: -100, personName: val };
                        });
                    }

                    var previousValue = scope.myModel;
                    if (!previousValue) {
                        previousValue = { personId: -1 };
                    }

                    scope.changePerson = function () {
                        if (scope.myModel == scope.addOption) {
                            var container = getContainer();
                            var el = $compile('<met-add-person></met-add-person>')(scope);
                            container.append(el);
                            showAddDialog(container);
                        } else {
                            previousValue = scope.myModel;
                        }
                    };

                    scope.$on('personAdded', function (event, data) {
                        scope.myModel = data.person;
                        var container = getContainer();
                        scope.onPersonAdded();
                        hideAddDialog(container);
                    });

                    scope.$on('clearPerson', function (event, data) {
                        var container = getContainer();
                        ctrl.$setViewValue(previousValue);
                        hideAddDialog(container);
                    });

                    function showAddDialog(container) {
                        container.children().css('display', 'none');
                        $('#onekey-add-object-dialog').css('display', 'table-cell');
                    }

                    function hideAddDialog(container) {
                        container.children().css('display', 'block');
                        $('#onekey-add-object-dialog').remove();
                    }

                    function getContainer() {
                        return element.parents('.add-new-item-container');
                    }

                    function openModal() {
                        var modalOptions = modalOptionsService.personModalOptions;
                        modalOptions.controller = function ($scope, $modalInstance) {
                            $scope.save = save;
                            $scope.cancel = cancel;
                            $scope.personInit = personInit;
                            function save() {
                                metPeople.create($scope.person, function (newPerson) {
                                    scope.$emit('personAdded', { person: newPerson });
                                    $modalInstance.close(newPerson);
                                }, function (error) {
                                    $scope.saving = false;
                                    $scope.valid = false;
                                    if ($scope.person.personName == "" || $scope.person.personName == undefined) {
                                        $scope.duplicate = true;
                                        $scope.error = error.data.message;
                                    }
                                    else {
                                        $scope.duplicate = true;
                                        $scope.error = error.data.message;
                                    }

                                    });
                            }

                            function cancel(reason) {
                                $modalInstance.dismiss(reason);
                            }

                            function personInit() {
                                $scope.messages = modalOptionsService.personModalOptions.messages;
                            }
                        };
                        var modalInstance = $modal.open(modalOptions);

                        modalInstance.result.then(function(success){
                            ctrl.$setViewValue(success.toJSON());
                        }, function(error){
                            ctrl.$setViewValue(previousValue);
                            scope.error = error;
                        });
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metAddTrade', [
        '$compile', '$parse', '$timeout', '$templateCache', 'localize', 'focus', 'trades',
        function ($compile, $parse, $timeout, $templateCache, metLocalize, metFocus, metTrades) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: '/OneKeyScripts/app/directives/trades/tradesAdd.html',
                scope: {},
                link: function (scope, element, attrs, ctrl) {
                    scope.messages = {
                        addDivision: metLocalize('titles', 'addDivision'),
                        cancel: metLocalize('commands', 'cancel'),
                        save: metLocalize('commands', 'save'),
                        tradeTitle: metLocalize('fieldNames', 'divisionName'),
                        required: metLocalize('validation', 'requiredError')
                    }

                    scope.trade = {
                        divisionName:''
                    }
                    scope.stuff = 'junk';
                    scope.saving = false;
                    scope.valid = true;
                    scope.duplicate = false;

                    scope.clearError = function () {
                        scope.duplicate = false;
                    }

                    scope.save = function () {
                        scope.saving = true;
                        metTrades.create(scope.trade, function (newTrade) {
                            scope.$emit('tradeAdded', { trade: newTrade });
                        }, function (error) {
                            scope.saving = false;
                            scope.valid = false;
                            if (scope.trade.divisionName == "" || scope.trade.divisionName == undefined) {
                                scope.duplicate = true;
                                scope.error = error.data.message;
                            }
                            else {
                                scope.duplicate = true;
                                scope.error = error.data.message;
                            }
                            
                        });
                    }

                    scope.cancel = function () {
                        scope.$emit('clearTrade', {});
                    }

                    $timeout(function () { metFocus('loaded'); }, 100);
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metTradeSelector', [
        '$compile', '$parse', '$modal', 'localize', 'urls', 'modalOptionsService',
        function ($compile, $parse, $modal, metLocalize, metUrls, modalOptionsService) {
            return {
                restrict: 'E',
                replace: true,
                require: 'ngModel',
                template:
    '<div><select class="form-control" name="{{ name }}" id="{{ name }}" tabindex="{{ tabindex }}" ng-disabled="metDisabled"' +
    ' ng-model="myModel" data-ng-options="trade.divisionName for trade in trades | append:addOption | orderBy:\'divisionName\' track by trade.divisionId" ' +
    ' data-ng-disabled="trades.length == 0 || metDisabled" data-ng-change="metResolveToPopup && (myModel == addOption) ? openModal() : changeTrade()" ' +
    ' data-met-select-placeholder="" data-met-focus-on="{{ metFocusOn }}" data-met-focus-on-if="metFocusOnIf()"> met-resolve-to-popup="metResolveToPopup">' +
    '</select></div>',
                scope: {
                    trades: '=metTrades',
                    myModel: '=ngModel',
                    name: '@',
                    tabindex: '@metTabindex',
                    onTradeAdded: '&metOnTradeAdded',
                    excludeAddOption: '@metExcludeAddOption',
                    includePlaceholder: '@metIncludePlaceholder',
                    metFocusOn: '@',
                    metFocusOnIf: '&',
                    metDisabled: '=?',
                    metResolveToPopup: '=?' 
                },
                link: function (scope, element, attrs, ctrl) {
                    
                    scope.messages = {
                        selectFromList: metLocalize('commands', 'selectFromList'),
                        addDivision: metLocalize('commands', 'addDivisionOption')
                    };

                    if (scope.myModel === undefined || scope.myModel.divisionId < 0) {
                        scope.myModel = { divisionId: -1 };
                    }

                    if (scope.myModel.divisionId < 0) {
                        scope.myModel = { divisionId: -1 };
                    };

                    if (!scope.excludeAddOption) {
                        scope.addOption = { divisionId: -100, divisionName: '' };
                        metLocalize('commands', 'addDivisionOption').promise.then(function (val) {
                            scope.addOption = { divisionId: -100, divisionName: val };
                        });
                    }

                    var previousValue = scope.myModel;
                    if (!previousValue) {
                        previousValue = { divisionId: -1 };
                    }

                    scope.openModal = openModal;
                    scope.changeTrade = function () {
                        if (scope.myModel == scope.addOption) {
                            var container = getContainer();
                            var el = $compile('<met-add-trade></met-add-trade>')(scope);
                            container.append(el);
                            showAddDialog(container);
                        } else {
                            previousValue = scope.myModel;
                        }
                    };

                    scope.$on('tradeAdded', function (event, data) {
                        scope.myModel = data.division;
                        var container = getContainer();
                        scope.onTradeAdded();
                        hideAddDialog(container);
                    });

                    scope.$on('clearTrade', function (event, data) {
                        var container = getContainer();
                        ctrl.$setViewValue(scope.previousValue);
                        hideAddDialog(container);
                    });

                    function showAddDialog(container) {
                        container.children().css('display', 'none');
                        $('#onekey-add-object-dialog').css('display', 'table-cell');
                    }

                    function hideAddDialog(container) {
                        container.children().css('display', 'block');
                        $('#onekey-add-object-dialog').remove();
                    }

                    function getContainer() {
                        return element.parents('.add-new-item-container');
                    }

                    function openModal () {
                        var modalOptions = modalOptionsService.sharedDefaultOptions;
                        modalOptions.templateUrl = metUrls('addTradeModal');
                        var modalInstance = $modal.open(modalOptions);

                        modalInstance.result.then(function(success){
                            scope.myModel = success.toJSON();
                        }, function(error){
                            console.log(error);
                            ctrl.$setViewValue(previousValue);
                            scope.error = error;
                        });
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metAddManufacturer', [
        '$compile', '$parse', '$timeout', '$templateCache', 'localize', 'focus', 'manufacturers',
        function ($compile, $parse, $timeout, $templateCache, metLocalize, metFocus, metManufacturers) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: 'OneKeyScripts/app/directives/manufacturers/manufacturersAdd.html',
                scope: {},
                link: function (scope, element, attrs, ctrl) {
                    scope.messages = {
                        addManufacturer: metLocalize('titles', 'addManufacturer'),
                        cancel: metLocalize('commands', 'cancel'),
                        save: metLocalize('commands', 'save'),
                        manufacturerTitle: metLocalize('fieldNames', 'manufacturerName'),
                        required: metLocalize('validation', 'requiredError')
                    }

                    scope.stuff = 'junk';
                    scope.manufacturer = {
                        manufacturerName:''
                    };
                    scope.saving = false;
                    scope.valid = true;
                    scope.duplicate = false;

                    scope.clearError = function () {
                        scope.duplicate = false;
                    }

                    scope.save = function () {
                        scope.saving = true;
                        metManufacturers.create(scope.manufacturer, function (newManufacturer) {
                            scope.$emit('manufacturerAdded', { manufacturer: newManufacturer });
                        }, function (error) {
                            scope.saving = false;
                            scope.valid = false;
                            if (scope.manufacturer.manufacturerName == "" || scope.manufacturer.manufacturerName == undefined) {
                                scope.duplicate = true;
                                scope.error = error.data.message;
                            }
                            else {
                                scope.duplicate = true;
                                scope.error = error.data.message;
                            }
                            
                        });
                    }

                    scope.cancel = function () {
                        scope.$emit('clearManufacturer', {});
                    }

                    $timeout(function () { metFocus('loaded'); }, 100);
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metManufacturerSelector', [
        '$compile', '$parse', 'localize', 'urls', 'manufacturers', 'modalOptionsService', '$modal',
        function ($compile, $parse, metLocalize, metUrls, metManufacturers, modalOptionsService, $modal) {
            return {
                restrict: 'E',
                replace: true,
                require: 'ngModel',
                template:
                '<div><select class="form-control" name="{{name}}" id="{{name}}" tabindex="{{tabindex}}" ng-disabled="metDisabled"' +
                ' ng-model="myModel" data-ng-options="mfr.manufacturerName for mfr in manufacturers | append:addOption | orderBy:\'manufacturerName\' track by mfr.manufacturerId" ' +
                ' data-ng-change="metResolveToPopup && (myModel == addOption) ? openModal() : changeManufacturer()" data-met-select-placeholder="" ' +
                ' data-met-focus-on="{{metFocusOn}}" data-met-focus-on-if="metFocusOnIf()" met-resolve-to-popup="metResolveToPopup"> ' +
                '</select></div>',
                scope: {
                    manufacturers: '=metManufacturers',
                    myModel: '=ngModel',
                    name: '@',
                    tabindex: '@metTabindex',
                    onManufacturerAdded: '&metOnManufacturerAdded',
                    excludeAddOption: '@metExcludeAddOption',
                    includePlaceholder: '@metIncludePlaceholder',
                    metFocusOn: '@',
                    metFocusOnIf: '&',
                    metDisabled: '=?',
                    primaryManufacturer: '=?',
                    metResolveToPopup: '=?'
                },
                link: function (scope, element, attrs, ctrl) {
                    scope.init = init();
                    scope.messages = {
                        selectFromList: metLocalize('commands', 'selectFromList'),
                        addManufacturerOption: metLocalize('commands', 'addManufacturerOption'),
                        addManufacturer: metLocalize('titles', 'addManufacturer'),
                        cancel: metLocalize('commands', 'cancel'),
                        save: metLocalize('commands', 'save'),
                        manufacturerTitle: metLocalize('fieldNames', 'manufacturerName'),
                        required: metLocalize('validation', 'requiredError')
                    };

                    if (!scope.excludeAddOption) {
                        scope.addOption = { manufactuerId: -100, manufacturerName: '' };
                        metLocalize('commands', 'addManufacturerOption').promise.then(function (val) {
                            scope.addOption = { manufacturerId: -100, manufacturerName: val };
                        });
                    }
                    scope.manufacturer = { manufacturerName: '' };

                    var previousValue = scope.myModel;
                    scope.openModal = openModal;

                    scope.changeManufacturer = function () {
                        if (scope.myModel == scope.addOption && !scope.metResolveToPopup) {
                            var container = getContainer();
                            var el = $compile('<met-add-manufacturer></met-add-manufacturer>')(scope);
                            container.append(el);
                            showAddDialog(container);
                        }

                        if (scope.myModel == scope.addOption) {
                            scope.error = false;
                        } 
                        else 
                            previousValue = scope.myModel;
                    };
                    scope.$on('manufacturerAdded', function (event, data) {
                        scope.myModel = data.manufacturer;
                        var container = getContainer();
                        scope.onManufacturerAdded();
                        hideAddDialog(container);
                    });

                    scope.$on('clearManufacturer', function (event, data) {
                        var container = getContainer();
                        ctrl.$setViewValue(scope.previousValue);
                        hideAddDialog(container);
                    });

                    function showAddDialog(container) {
                        container.children().css('display', 'none');
                        $('#onekey-add-object-dialog').css('display', 'table-cell');
                    }

                    function hideAddDialog(container) {
                        container.children().css('display', 'block');
                        $('#onekey-add-object-dialog').remove();
                    }

                    function getContainer() {
                        return element.parents('.add-new-item-container');
                    }

                    function openModal () {
                        var modalOptions = modalOptionsService.sharedDefaultOptions;
                        modalOptions.templateUrl = metUrls('addManufacturerModal');
                        var modalInstance = $modal.open(modalOptions);

                        modalInstance.result.then(function(success){
                            ctrl.$setViewValue(success.toJSON());
                        }, function(error){
                            ctrl.$setViewValue(previousValue);
                            scope.error = error;
                        });
                    }

                    function init(){
                        var initModelCopy = angular.copy(scope.myModel);
                    }
                    
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metDocuments', [
        'urls', 'localize', 'userItems', 'dates',
        function (metUrls, metLocalize, metUserItems, metDates) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryItemDocuments'),
                scope: {
                    item: '='
                },
                link: function (scope, element, attrs) {
                    scope.isLoading = true;

                    scope.messages = {
                        noNotes: metLocalize('messages', 'noDocuments'),
                    }

                    function init() {
                        scope.isLoading = false;

                    }

                    init();
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metEditDetails', [
        '$filter', 'urls', 'localize', 'itemFieldFactory', 'dates',
        function ($filter, metUrls, metLocalize, metItemFields, metDates) {
            return {
                restrict: 'EA',
                replace: false,
                templateUrl: metUrls('inventoryEditItemDetails'),
                scope: {
                    item: '=',
                    saveItem: '&'
                },
                link: function (scope, element, attrs) {
                    scope.isUpdating = false;
                    scope.itemFields = metItemFields;
                    scope.workingItem;
                    scope.serviceDateForPicker;
                    scope.isLoaded = false;
                    scope.messages = {
                        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')
                    }
                    
                    scope.imageUploadUrl = metUrls('imagesUserItemsApi');
                    scope.datePickerOptions = metDates.getDatePickerOptions('top');
	                scope.closeDetails = function(saveItem) {
		                if (saveItem) {
			                scope.item.toolNumber = scope.workingItem.toolNumber;
			                scope.item.manufacturer = scope.workingItem.manufacturer;
			                scope.item.modelNumber = scope.workingItem.modelNumber;
			                scope.item.serialNumber = scope.workingItem.serialNumber;
			                scope.item.itemDescription = scope.workingItem.itemDescription;
			                scope.item.category = scope.workingItem.category;
			                scope.item.trade = scope.workingItem.trade;
			                scope.item.imageUrl = scope.workingItem.imageUrl != "" ? scope.workingItem.imageUrl : scope.item.defaultImageUrl;
			                scope.saveItem();

			                scope.item.imageAlternates = scope.workingItem.imageAlternates;
		                } else {
			                setItem();
		                }
	                }

	                scope.openDetails = function () {
	                    scope.workingItem = angular.copy(scope.item);
                        scope.isLoaded = true;
                    }

                    function setItem() {
                        scope.isLoaded = false;
                        scope.workingItem = angular.copy(scope.item);
                    }

                    function init() {
                        setItem();
                        metItemFields.init();
                    }

                    init();
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metFileUpload', [
        '$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('inventoryFileUpload'),
                scope: {
                    item: '=',
                    reloadItems: '&'
                },
                link: function (scope) {
                    scope.isLoading = true;
                    scope.dateFormat = metDates.date(true);
                    scope.uploads = [];
                    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')
                    };

                    scope.uploadUrl = metUrls('uploadsApi');

                    scope.$watch('files', function () {
                        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) {
                            for (var i = 0; i < files.length; i++) {
                                var file = files[i];
                                if (!file.$error) {
                                    if (file.size > 10485760) {
                                        metNotify.error(scope.messages.fileTooLarge.value);
                                        return;
                                    }
                                    Upload.upload({
                                        url: scope.uploadUrl + '/' + scope.item.itemId,
                                        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, status, headers, config) {
                                        scope.reloadItems();
                                        $timeout(function () {
                                            scope.log = 'file: ' + config.file.name + ', Response: ' + JSON.stringify(data) + '\n' + scope.log;
                                        });
                                    }).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';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metGeneralDetails', [
        '$filter', 'urls', 'localize', 'dates', 'locations', 'people', 'itemStatuses', 'language',
        function ($filter, metUrls, metLocalize, metDates, metLocations, metPeople, metItemStatuses, metLanguage) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryGeneralDetailsLink'),
                scope: {
                    item: '=',
                    locations: '=',
                    people: '=',
                    loadItems: '&',
                    saveItem: '&',
                },
                link: function (scope, element, attrs) {
                	scope.language = metLanguage.getLocale();
                    scope.longDateFormat = metDates.longDateFormat;
                    scope.serviceDateForPicker;
                    scope.datePickerOptions = metDates.getDatePickerOptions('top');
                    scope.lastReportedDate = metDates.convertUtcToLocal(scope.item.lastReported, metDates.longDateFormat);
                    scope.messages = {
                        toolNumber: metLocalize('fieldNames', 'toolNumber'),
                        serviceDate: metLocalize('fieldNames', 'serviceDate'),
                        location: metLocalize('fieldNames', 'assignedLocation'),
                        person: metLocalize('fieldNames', 'assignedPerson'),
                        status: metLocalize('fieldNames', 'itemStatus'),
                        coinCell: metLocalize('fieldNames', 'coinCellLevel')
                    }

                    scope.$watch('item.location', function (newValue, oldValue) {
                        if (newValue === oldValue) {
                            return;
                        }

                        if (newValue.locationId > -2) {  //ignore add item selector
                            scope.saveForm();
                        }
                    });

                    scope.$watch('item.person', function (newValue, oldValue) {
                        if (newValue === oldValue) {
                            return;
                        }

                        if (newValue.personId > -2) {  //ignore add item selector
                            scope.saveForm();
                        }
                    });

                    scope.$watch('item.status', function (newValue, oldValue) {
                        if (newValue === oldValue) {
                            return;
                        }

                        scope.saveForm();

                        if (scope.item.securityContext && newValue == 1) {
                            scope.item.securityContext.shouldLock = 1;
                            scope.item.securityContext.shouldUnlock = 0;
                        }
                    });

                    scope.saveDatePicker = function () {
                        var serviceDate = document.querySelector('#detailServiceDate').value;
                        scope.item.serviceDate = serviceDate.length > 0 ? moment(serviceDate, metDates.date(false)).format(metDates.api) : undefined;
                        scope.saveForm();
                    }

                    scope.saveForm = function () {
                        scope.saveItem();
                    }

                    scope.isLoaded = false;

                    scope.defaultImage = function () {
                        if (scope.item.isPrimaryManufacturer) {
                            scope.item.defaultImageUrl = metUrls('milwaukeeDefault');
                            return scope.item.defaultImageUrl;
                        }
                        else {
                            scope.item.defaultImageUrl = metUrls('otherDefault');
                            return scope.item.defaultImageUrl;
                        }
                    }

                    function init() {
                        scope.serviceDateForPicker = $filter('date')(scope.item.serviceDate, metDates.date(true));
                        metItemStatuses.getAll(function (data) {
                            scope.statuses = data.items;
                            scope.isLoaded = true;

                        });
                        
                    }

                    init();
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metHistory', [
        'urls', 'localize', 'userItems', 'dates',
        function (metUrls, metLocalize, metUserItems, metDates) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryItemHistory'),
                scope: {
                    item: '='
                },
                link: function (scope, element, attrs) {
                    scope.isLoading = true;
                    scope.noHistory = false;
                    scope.dateAdded = '';
                    scope.historyList = [];
                    scope.dateFormat = metDates.date(true);
                    
                    scope.messages = {
                        historyLoading: metLocalize('messages', 'itemHistoryLoading'),
                        noHistory: metLocalize('messages', 'itemHistoryEmpty'),
                        location: metLocalize('fieldNames', 'locationId'),
                        place: metLocalize('fieldNames', 'placeId'),
                        status: metLocalize('fieldNames', 'status'),
                        date: metLocalize('fieldNames', 'date'),
                        time: metLocalize('fieldNames', 'time'),
                        totalDays: metLocalize('fieldNames', 'totalDays'),
                        weTrackForYou: metLocalize('messages', 'weTrackForYou'),
                        historyEmptyMessage: metLocalize('messages', 'historyEmptyMessage'),
                        toolAdded: metLocalize('messages', 'toolAdded'),
                        at: metLocalize('messages', 'at')
                    }

                    function init() {
                        metUserItems.history(scope.item.itemId,
							function (data) {
								scope.historyList = data.historyList;
                                for (var i = 0; i < scope.historyList.length; i++) {
                                    var convertedTime = metDates.convertUtcToLocal(scope.historyList[i].changeDate, metDates.shortTime);
                                    var convertedDate = metDates.convertUtcToLocal(scope.historyList[i].changeDate, scope.dateFormat);
                                    scope.historyList[i].changeTime = convertedTime;

                                    scope.historyList[i].changeDate = convertedDate;
								}
                                scope.item.historyCount = data.total;
                                scope.isLoading = false;
                                scope.noHistory = scope.historyList.length == 0;
                                if (scope.noHistory) {
                                    scope.timeAdded = metDates.convertUtcToLocal(scope.item.dateAdded, metDates.shortTime);
                                    scope.dateAdded = metDates.convertUtcToLocal(scope.item.dateAdded, scope.dateFormat);
                                }
                            },
                            function () {
                                scope.isLoading = false;
                            }
                        );
                    }

                    init();
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metNotes', [
        '$compile', 'urls', 'localize', 'itemNotes', 'dates', '$modal', 'modalOptionsService',
        function ($compile, metUrls, metLocalize, metItemNotes, metDates, $modal, modalOptionsService) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryItemNotes'),
                scope: {
                    item: '='
                },
                link: function (scope, element, attrs) {
                    scope.isLoading = true;
                    scope.noNotes = false;
                    scope.editView = false;
                    scope.notes = [];
                    scope.selectedNote = '';
                    scope.getContainer = getContainer;
                    scope.addNewNote = false;
                    scope.newNote = { text: "", userItemId: scope.item.itemId };
                    scope.messages = {
                        loadingNotes: metLocalize('messages', 'loadingItemNotes'),
                        noNotes: metLocalize('messages', 'noItemNotes'),
                        addNote: metLocalize('messages', 'addItemNote'),
                        save: metLocalize('commands', 'save'),
                        cancel: metLocalize('commands', 'cancel'),
                        noteRequired: metLocalize('messages', 'NoteRequired'),
                        notesMaxLength: metLocalize('messages', 'NotesMaxLength'),
                        edit: metLocalize('fieldNames', 'edit'),
                        remove: metLocalize('fieldNames', 'remove'),
                        delete: metLocalize('commands', 'delete'),
                        makeANote: metLocalize('messages', 'makeANote'),
                        emptyNotesText: metLocalize('messages', 'emptyNotesText'),
                        editNote: metLocalize('fieldNames', 'editNote'),
                        notes: metLocalize('fieldNames', 'notes'),
                        noteCharacterMax: metLocalize('messages', 'noteCharacterMax'),
                        deleteNoteMessage: metLocalize('messages', 'deleteNoteMessage'),
                        deleteNoteTitle: metLocalize('messages', 'deleteNoteTitle')
                    }

                    scope.setNoteAdd = function (isAdd) {
                        scope.addNewNote = isAdd;
                        scope.editView = false;
                        scope.newNote.text = "";
                        if (isAdd) {
                            scope.addNote();
                        } else {
                            scope.cancel();
                        }
                    }

                    scope.saveNote = function () {
                        scope.isLoading = true;
                        metItemNotes.create(scope.newNote,
                            function (data) {
                                scope.setNoteAdd(false);
                                loadNotes();
                            },
                            function () {
                                scope.isLoading = false;
                                openModal();
                            }
                        );
                    }

                    scope.setEdit = function (isEdit) {
                        scope.noNotes = false;
                        scope.addNewNote = false;
                        scope.editView = isEdit;
                        if (!isEdit) {
                            loadNotes();
                            scope.cancel();
                        } else {
                            scope.editNote(scope.selectedNote);
                        }
                        
                    }

                    scope.saveEdit = function () {
                        metItemNotes.edit(scope.selectedNote, function (data) { scope.setEdit(false); }, function (error) { openModal(); });
                    }

                    scope.removeNote = function () {
                        metItemNotes.remove(scope.selectedNote, function (data) { loadNotes(); }, function (error) { openModal(); });
                    }

                    scope.getLocalUtcDate = function (date) {
                        var format = metDates.date(true);
                        return metDates.convertUtcToLocal(date, format);
                    }

                    scope.setSelectedNote = function (noteId) {
                       var result = scope.notes.filter(function (note) {
                            return note.id === noteId;
                        });

                       scope.selectedNote = result[0];
                    }

                    function init() {
                        loadNotes();
                    }

                    function loadNotes() {
                        scope.isLoading = true;
                        scope.noNotes = false;

                        metItemNotes.get(scope.item.itemId,
                            function (data) {
                                scope.isLoading = false;
                                scope.notes = data.items;
                                scope.noNotes = data.items.length === 0;
                                scope.selectedNote = data.items[0];
                            },
                            function () {
                                scope.isLoading = false;
                            }
                        );
                    }

                    function openModal() {
                        $modal.open(modalOptionsService.generalErrorModalOptions);
                    }

                    function getContainer() {
                        return element.parents('.item-container');
                    }

                    function scrollTo() {
                        setTimeout(function() {
                            var $notesContainer = document.getElementById('item-notes');
                            if ($notesContainer) {
                                $notesContainer.scrollTop = $notesContainer.scrollHeight;
                            }
                        }, 10);
                    }

                    scope.$watch('newNote.text', function() { scrollTo(); });
                    scope.$watch('selectedNote.text', function() { scrollTo(); });

                    scope.addNote = function () {
                        var container = getContainer();
                        var notesEdit = $(container).children('.notes-edit');
                        if (notesEdit.length > 0) {
                            removeCharacterCounterElements();
                            setEditDialogVisibility(container, 'visible');
                        } else {
                            var el = $compile(
                                '<met-notes-edit data-item="item" data-note-items="itemNotes" data-add-new-note="addNewNote" data-add-note="saveNote()"></<met-notes-edit>'
                            )(scope);
                            container.append(el);
                            showAddDialog(container);
                        }
                    }

                    function showAddDialog(container) {
                        container.children().css('display', 'none');
                        $('notes-edit').css('display', 'table-cell');

                    }

                    scope.editNote = function (selectedNote) {
                        scope.editView = true;
                        scope.selectedNote = selectedNote;
                        var container = getContainer();
                        var notesEdit = $(container).children('.notes-edit');
                        if (notesEdit.length > 0) {
                            removeCharacterCounterElements();
                            setEditDialogVisibility(container, 'visible');
                        } else {
                            var el = $compile(
                                '<met-notes-edit data-item="item" data-note-items="itemNotes" selected-note="selectedNote" data-save-note="saveEdit()"></<met-notes-edit>'
                            )(scope);
                            container.append(el);
                            showEditDialog(container, selectedNote);
                        }
                    }

                    function showEditDialog(container, selectedNote) {
                        container.children().css('display', 'none');
                        $('.notes-edit').css('display', 'table-cell');
                        scope.itemNote = angular.copy(selectedNote);
                    }

                    function setEditDialogVisibility(container, isVisible) {
                        container.children().css('display', 'block');
                        var cssVisibility;
                        if (isVisible) {
                            cssVisibility = 'visible';
                        } else {
                            cssVisibility = 'hidden';
                        }
                        $('.notes-edit').css('visibility', cssVisibility);
                    }

                    function removeCharacterCounterElements() {
                        // -- need to remove this element because angular material appends a new one each time the input container is made visible
                        $('.md-char-counter').remove();
                    }

                    scope.cancel = function () {
                        var container = getContainer();
                        scope.editView = false;
                        scope.addNewNote = false;
                        setEditDialogVisibility(container, false);
                    }

                    init();
                }
            };
        }
    ]);
}());

(function (module) {
    'use strict';

    var metNotesEdit = function () {

        return {
            restrict: 'E',
            replace: true,
            transclude: true,
            templateUrl: '/OneKeyScripts/app/directives/inventory/details/metNotesEdit.directive.html',
            scope: {
                item: '=',
                itemNote: '=?'
            },
            link: function (scope) {
                scope.addEditNote = true;
            }
        }
    };

    module.directive('metNotesEdit', metNotesEdit);

}(angular.module('oneKeyApp')));

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metNotifications', [
        '$filter', 'urls', 'localize','dates', 'notifications', '$rootScope',
        function ($filter, metUrls, metLocalize, metDates, metAlerts, $rootScope) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryItemNotifications'),
                scope: {
                    item: '=',
                    userItem: '=',
                    itemStatus: '=',
                    saveItem: '&',
                    selectedStatus: '=',
                    statuses: '='
                },
                link: function (scope, element, attrs) {
                    scope.isLoading = true;
                    scope.noNotifications = false;
                    scope.notificationList = [];

                    scope.messages = {
                        loadingAlerts: metLocalize('messages', 'loadingAlerts'),
                        noAlerts: metLocalize('messages', 'userNotificationsEmptyAlerts'),
                        dateReceived: metLocalize('messages', 'dateRecieved'),
                        read: metLocalize('messages', 'read'),
                        alert: metLocalize('messages', 'alert'),
                        dismiss: metLocalize('commands', 'dismiss'),
                        serviceStatus: metLocalize('fieldNames', 'itemStatus_Service'),
                        setToService: metLocalize('messages', 'setToService'),
                        delete: metLocalize('commands', 'delete'),
                        deleteConfirm: metLocalize('messages', 'deleteAlertConfirm')
                    }

                    scope.getLocalUtcDate = function (date) {
                        var format = metDates.date(true);
                        return metDates.convertUtcToLocal(date, format);
                    };

                    scope.getLocalUtcTime = function (date) {
                        return metDates.convertUtcToLocal(date, metDates.shortTime);
                    };

                    scope.$on('alert-deleted',
                        function (event, args) {
                            loadNotifications();
                        });

                    var serviceStatusId = 5;
                    scope.showServiceLink = function (notificationTypeId) {
                        var showServiceLink = false;
                        if (scope.item.status !== serviceStatusId) {
                            switch (notificationTypeId) {
                                case 'ServiceAlert':
                                case 'ServiceDateAlert':
                                case 'ServiceDateWarning':
                                case 'ServiceWarning':
                                    showServiceLink = true;
                                    break;
                                default:
                                    showServiceLink = false;
                                    break;
                            }
                        }

                        return showServiceLink;
                    };

                    scope.setStatusToService = function () {
                        scope.item.status = serviceStatusId;
                        scope.itemStatus = scope.messages.serviceStatus.value;
                        var result = $.grep(scope.statuses, function (status) { return status.statusId === serviceStatusId; });
                        result[0].itemCount += 1;
                        scope.selectedStatus.statusName = result[0].statusName;
                        scope.selectedStatus.statusId = result[0].statusId;
                        scope.selectedStatus.itemCount = result[0].itemCount;
                        scope.saveItem();
                    };

                    scope.acknowledge = function (notification, $event) {
                        metAlerts.acknowledge(notification,
                            function () {
                                scope.item.notificationCount--;
                                scope.userItem.alertCount--;
                                $rootScope.$broadcast('update-notifications-count', {});
                                $filter('filter')(scope.notificationList, { id: notification.id })[0].acknowledgedOn = Date.now();
                            }
                        );
                    };
                    
                    scope.dismiss = function (notification, $event) {
                        metAlerts.dismiss(notification.id,
                            function () {
                                scope.item.serviceDate = null;
                                scope.userItem.alertCount--;
                                $rootScope.$broadcast('update-notifications-count', {});
                                loadNotifications();
                            }
                        );
                    }

                    function init() {
                        loadNotifications();
                    }

                    function loadNotifications() {
                        scope.isLoading = true;
                        metAlerts.getItemNotifications(scope.item.itemId,
                            function (data) {
                                scope.notificationList = data.items;
                                scope.isLoading = false;
                                scope.noNotifications = data.items.length == 0;

                                var unacknowledgedNotifications = $filter('filter')(data.items, { acknowledgedOn: null })
                                scope.item.notificationCount = unacknowledgedNotifications.length;
                                var result = $.grep(scope.notificationList, function (alert) { return alert.notificationType === 'ServiceDateAlert'; });
                                if (result.length > 0) {
                                    scope.item.hasServiceDateAlert = true;
                                } else {
                                    scope.item.hasServiceDateAlert = false;
                                }
                                var geofenceAlert = $.grep(scope.notificationList, function (alert) { return alert.notificationType === 'BrokeGeofenceAlert'; });
                                if (geofenceAlert.length > 0) {
                                    scope.item.brokeGeofence = true;
                                } else {
                                    scope.item.brokeGeofence = false;
                                }
                            },
                            function () {
                                scope.isLoading = false;
                            }
                       );
                    }

                    init();
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metOverview', [
        'urls', 'localize', 'dates',
        function (metUrls, metLocalize, metDates) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryItemOverview'),
                scope: {
                    item: '='
                },
                link: function (scope, element, attrs) {
                    scope.lastSeenDate = metDates.convertUtcToLocal(scope.item.lastSeen, metDates.longDateTimeFormat);
                    if (scope.item.cycleInformation) {
                        scope.lastSyncDate = metDates.convertUtcToLocal(scope.item.cycleInformation.lastSync, metDates.longDateTimeFormat);
                    }

                    scope.messages = {
                        cyclesLeft: metLocalize('fieldNames', 'cyclesLeft'),
                        coinCellStatus: metLocalize('messages', 'coinCellCapacity'),
                        totalCycles: metLocalize('fieldNames', 'TotalCycles'),
                        displaySyncData: metLocalize('messages', 'displaySyncData'),
                        lastSeen: metLocalize('fieldNames', 'lastSeen'),
                        usage: metLocalize('fieldNames', 'usage'),
                        lastSync: metLocalize('fieldNames', 'lastSync'),
                        cyclesSinceLastService: metLocalize('fieldNames', 'cyclesSinceLastService')
                    }

                    scope.getAlertClass = function (alertLevel) {
                        var alertClass = 'item-good';
                        switch (alertLevel) {
                            case 1:
                                alertClass = 'item-warning';
                                break;
                            case 2:
                                alertClass = 'item-alert';
                                break;
                        }
                        return alertClass;
                    }
                }
            };
        }
    ]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metPurchaseInfo', [
        '$compile', '$filter', 'urls', 'localize', 'dates', 'userItems',
        function ($compile, $filter, metUrls, metLocalize, metDates, metUserItems) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryItemPurchaseInfo'),
                scope: {
                    item: '=',
                    saveItem: '&',
                    tabSelectedIndex: '='
                },
                link: function (scope, element, attrs) {
                	scope.longDateFormat = metDates.longDateFormat;
                    scope.purchaseDateForPicker;
                    scope.editView;
                    scope.addView;
                    scope.emptyView = false;
                    scope.tabSelectedIndex;
                    scope.datePickerOptions = metDates.getDatePickerOptions('top');
                    scope.getContainer = getContainer;
                    scope.messages = {
                        purchaseLocation: metLocalize('fieldNames', 'purchaseLocation'),
                        purchaseDate: metLocalize('fieldNames', 'datePurchased'),
                        value: metLocalize('fieldNames', 'price'), 
                        orderInfo: metLocalize('fieldNames', 'orderInformationImageUrl'), 
                        itemization: metLocalize('fieldNames', 'ItemizationImageUrl'),
                        date: metLocalize('fieldNames', 'date'),
                        itemValue: metLocalize('fieldNames', 'ItemValue'),
                        serviceType: metLocalize('fieldNames', 'serviceType'),
                        location: metLocalize('fieldNames', 'location'),
                        place: metLocalize('fieldNames', 'placeId'),
                        purchasePlace: metLocalize('fieldNames', 'purchasePlace'),
                        purchaseInformation: metLocalize('fieldNames', 'purchaseInformation'),
                        edit: metLocalize('fieldNames', 'edit'),
                        save: metLocalize('commands', 'save'),
                        cancel: metLocalize('commands', 'cancel'),
                        addInfo: metLocalize('commands', 'addInfo'),
                        saveForLater: metLocalize('messages', 'saveForLater'),
                        saveForLaterConversational: metLocalize('messages', 'saveForLaterConversational'),
                        emptyPurchaseInfoText: metLocalize('messages', 'emptyPurchaseInfoText'),
                        editPurchaseInfo: metLocalize('messages', 'editPurchaseInfo'),
                        addPurchaseInfo: metLocalize('messages', 'addPurchaseInfo')
                    }

                    scope.purchaseInformation = {};

                    scope.purchaseUploadUrl = metUrls('imagesProofOfPurchaseApi');
                    
                    scope.$watch('item.itemizationImageAlternates', function (newValue, oldValue) {
                        if (newValue === oldValue) {
                            return;
                        }
                       scope.item.itemizationImageUrl = newValue.smallUrl;
                        scope.saveForm();
                    });

                    scope.$watch('item.orderInformationImageAlternates', function (newValue, oldValue) {
                        if (newValue === oldValue) {
                            return;
                        }
                        scope.item.orderInformationImageUrl = newValue.smallUrl;
                        scope.saveForm();
                    });

                    scope.savePurchaseInfo = function() {
                        var purchaseDate = $filter('date')(scope.item.datePurchased, metDates.date(true));

                        if (document.querySelector('#purchaseDateInput')) {
                            purchaseDate = document.querySelector('#purchaseDateInput').value;
                        }
                        scope.item.datePurchased =(purchaseDate && purchaseDate.length > 0) ? moment(purchaseDate, metDates.date(false)).format(metDates.api) : undefined;
                        scope.item.purchaseLocation = scope.item.purchaseInfoEditLocation;
                        if (scope.item.purchaseInfoEditValue) {
                            scope.item.price = scope.item.purchaseInfoEditValue;
                        } else {
                            scope.item.price = null;
                        }

                        scope.emptyView =
                            (!(scope.item.datePurchased || scope.item.purchaseLocation || scope.item.price));
                    };

                    scope.saveForm = function () {
                        scope.saveItem();
                        scope.setEdit(false);
                        scope.purchaseDateForPicker = $filter('date')(scope.item.datePurchased, metDates.date(true));   
                    }

                    scope.isLoaded = false;
                    function init() {
                    	scope.purchaseDateForPicker = $filter('date')(scope.item.datePurchased, metDates.date(true));
                        scope.isLoaded = true;
                        scope.emptyView = (!(scope.item.purchaseLocation || scope.item.price || scope.purchaseDateForPicker));
                    }

                    scope.cancel = function() {
                        var container = getContainer();
                        scope.setEdit(false);
                        setEditDialogVisibility(container, false);
                    }

                    scope.setEdit = function (isEdit, isCancel) {
                        var container = getContainer();
                        if (isCancel) {
                            scope.emptyView = (!(scope.item.purchaseLocation || scope.item.price || scope.purchaseDateForPicker));
                            scope.getItemDetails(isCancel);
                            return;
                        }
                        scope.editView = isEdit;
                        if (!isEdit) {
                            hideEditDialog(container);
                        }
                    }

                    scope.getItemDetails = function (isCancel) {
                        metUserItems.get(scope.item.itemId, function (response) {
                            scope.item = response;
                            scope.purchaseDateForPicker = $filter('date')(scope.item.datePurchased, metDates.date(true));
                            scope.loading = false;
                            if (isCancel) {
                                scope.editView = false;
                            }
                        });
                    }

                    scope.editPurchaseInformation = function (purchaseInformationItem, isAdd) {
                        scope.addView = isAdd;
                        scope.editView = true;
                        scope.purchaseInformation = purchaseInformationItem;
                        var container = getContainer();
                        var purchaseInfoEdit = $(container).children('.purchase-info-edit');
                        if (purchaseInfoEdit.length > 0) {
                            setEditDialogVisibility(container, 'visible');
                        }
                        else {
                            var el = $compile(
                                '<met-purchase-info-edit data-item="item" data-save-item="saveForm()" data-add-view="addView" purchase-information="purchaseInformation"></met-purchase-info-edit>'
                            )(scope);
                            container.append(el);
                            showEditDialog(container, purchaseInformationItem);
                        }
                    }

                    function getContainer() {
                        return element.parents('.item-container');
                    }

                    function showEditDialog(container, purchaseInformationItem) {
                        container.children().css('display', 'none');
                        $('.purchase-info-edit').css('display', 'table-cell');
                        scope.purchaseInformation = angular.copy(purchaseInformationItem);
                    }

                    function hideEditDialog(container) {
                        container.children().css('display', 'block');
                        $('.purchase-info-edit').remove();
                    }

                    function setEditDialogVisibility(container, isVisible) {
                        container.children().css('display', 'block');
                        var cssVisibility = isVisible ? 'visible' : 'hidden';
                        $('.purchase-info-edit').css('visibility', cssVisibility);
                    }

                    scope.isNumberKey = function($event) {
                        if (isNaN(String.fromCharCode($event.keyCode)) && $event.which !== 8 && $event.which !== 46) {
                            $event.preventDefault();
                        }
                    }

                    init();
                }
            };
        }
    ]);
}());

(function (module) {
    'use strict';

    var metPurchaseInfoEdit = function ($compile, urls, localize, dates, metNotify, $filter) {

        return {
            restrict: 'E',
            replace: true,
            transclude: true,
            templateUrl: '/OneKeyScripts/app/directives/inventory/details/metPurchaseInfoEdit.directive.html',
            scope: {
                item: '=',
                purchaseInformation: '=?',
                saveItem: '&'
            },
            link: function (scope, element, attrs) {
                scope.datePickerOptions = dates.getDatePickerOptions('top');
                scope.getContainer = getContainer;
                scope.isEdit = false;
                scope.purchaseDateForPicker;
                scope.item.purchaseInfoEditLocation;
                scope.item.purchaseInfoEditValue;
                scope.editView;

                if (scope.purchaseInformation !== undefined) {
                    scope.purchaseInfo = scope.purchaseInformation;
                    scope.purchaseDateForPicker = $filter('date')(scope.purchaseInfo.datePurchased, dates.date(true));
                    scope.item.purchaseInfoEditLocation = scope.purchaseInfo.purchaseLocation;
                    scope.item.purchaseInfoEditValue = scope.purchaseInfo.price;
                    scope.isEdit = true;
                    scope.editView = true;
                }

                function getContainer() {
                    return element.parents('#itemDetails');
                }
            }
        }
    };

    metPurchaseInfoEdit.$inject = ['$compile', 'urls', 'localize', 'dates', 'notify', '$filter'];
    module.directive('metPurchaseInfoEdit', metPurchaseInfoEdit);

}(angular.module('oneKeyApp')));

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metServiceRecordUpload', [
        '$compile', '$filter', 'urls', 'localize', 'itemNotes', 'dates', 'uploads', 'Upload', '$timeout', 'notify', 'serviceRecords',
        function ($compile, $filter, metUrls, metLocalize, metItemNotes, metDates, metUploadService, Upload, $timeout, metNotify, serviceRecords) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryServiceRecordUpload'),
                scope: {
                    reloadItems: '&',
                    item: '=',
                    selectedType: '=',
                    hasUploads: '=',
                    userItem: '=',
                    isEdit: '='
                },
                link: function (scope) {
                    scope.isLoading = true;
                    scope.dateFormat = metDates.date(true);
                    scope.uploads = [];
                    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'),
                        upload: metLocalize('fieldNames', 'upload'),
                        fileTooLarge: metLocalize('messages', 'fileTooLarge'),
                        serviceDateRequired: metLocalize('messages', 'serviceDateRequired')
                    };

                    scope.uploadUrl = metUrls('serviceRecordUploadsApi');

                    scope.$watch('files', function () {
                        scope.upload(scope.files);
                    });
                    scope.$watch('file', function () {
                        if (scope.file != null) {
                            scope.upload([scope.file]);
                        }
                    });
                    scope.log = '';

                    scope.upload = function (files) {
                        if (scope.item.id === undefined && files && files.length) {
                            for (var i = 0; i < files.length; i++) {
                                var file = files[i];
                                if (file.size > 10485760) {
                                    metNotify.error(scope.messages.fileTooLarge.value);
                                    return;
                                }
                                if (file.$error === 'pattern') {
                                    metNotify.error(scope.messages.unsupportedUploadFormatImageOrPdf.value);
                                    return;
                                }
                            }
                            if (scope.item.date === undefined || scope.item.date === null) {
                                metNotify.error(scope.messages.serviceDateRequired.value);
                                return;
                            }

                            var serviceDate = scope.isEdit ? document.querySelector('#serviceDateInputEdit').value : document.querySelector('#serviceDateInputAdd').value;

                            scope.item.date = serviceDate.length > 0 ? moment(serviceDate, metDates.date(false)).format(metDates.api) : moment().format(metDates.getDatePickerOptions().format);
                            if (scope.item.date < scope.epochStart) {
                                scope.item.date = scope.epochStart;
                            }

                            scope.item.userItemId = scope.userItem.id;
                            scope.item.typeId = scope.selectedType.id;
                            serviceRecords.create(scope.item,
                                function (data) {
                                    var itemId = data.id;
                                    if (files && files.length) {
                                        for (var i = 0; i < files.length; i++) {
                                            var file = files[i];
                                            if (!file.$error) {
                                                Upload.upload({
                                                    url: scope.uploadUrl + '/' + itemId,
                                                    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, status, headers, config) {
                                                    scope.isEdit = true;
                                                    scope.item.id = itemId;
                                                    scope.reloadItems(true);
                                                    $timeout(function () {
                                                        scope.log = 'file: ' + config.file.name + ', Response: ' + JSON.stringify(data) + '\n' + scope.log;
                                                    });
                                                }).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 (data) {
                                });

                        }
                        else {
                            if (files && files.length) {
                                for (var i = 0; i < files.length; i++) {
                                    var file = files[i];
                                    if (!file.$error) {
                                        if (file.size > 10485760) {
                                            metNotify.error(scope.messages.fileTooLarge.value);
                                            return;
                                        }
                                        Upload.upload({
                                            url: scope.uploadUrl + '/' + scope.item.id,
                                            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, status, headers, config) {
                                            scope.reloadItems(true);
                                            $timeout(function () {
                                                scope.log = 'file: ' + config.file.name + ', Response: ' + JSON.stringify(data) + '\n' + scope.log;
                                            });
                                        }).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';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.directive('metUploads', [
        '$compile', '$filter', 'urls', 'localize', 'itemNotes', 'dates', 'uploads', '$mdDialog',
        function ($compile, $filter, metUrls, metLocalize, metItemNotes, metDates, metUploadService, $mdDialog) {
            return {
                restrict: 'E',
                replace: true,
                templateUrl: metUrls('inventoryItemUploads'),
                scope: {
                    item: '='
                },
                link: function (scope) {
                    scope.isLoading = true;
                    scope.dateFormat = metDates.date(true);
                    scope.uploads = [];
                    scope.messages = {
                        save: metLocalize('commands', 'save'),
                        cancel: metLocalize('commands', 'cancel'),
                        edit: metLocalize('fieldNames', 'edit'),
                        view: metLocalize('commands', 'view'),
                        remove: metLocalize('fieldNames', 'remove'),
                        uploadedItems: metLocalize('fieldNames', 'uploadedItems'),
                        delete: metLocalize('commands', 'delete'),
                        deleteConfirm: metLocalize('messages', 'deleteUploadConfirm'),
                        everythingInOneSpot: metLocalize('messages', 'everythingInOneSpot'),
                        emptyUploadsText: metLocalize('messages', 'emptyUploadsText')
                    };

                    scope.delete = function (id) {
                        metUploadService.remove(id, function () {
                            scope.loadUploads();
                        });
                    }

                    scope.loadUploads = function () {
                        metUploadService.getUploads(scope.item.itemId, function (data) {
                            scope.uploads = data;
                            for (var i = 0; i < scope.uploads.length; i++) {
                                scope.uploads[i].createdOnLocal = metDates.convertUtcToLocal(scope.uploads[i].createdOn, scope.dateFormat);
                            }
                        });
                    }

                    scope.update = function (userItemResource) {
                        metUploadService.update(userItemResource, function () {
                            scope.loadUploads();
                        });
                    }

                    scope.canEdit = function (uploadItem) {
                        var inputField = document.getElementById(uploadItem.resourceTitle + uploadItem.id);
                        inputField.readOnly = !uploadItem.canDelete;
                    };

                    function init() {
                        scope.loadUploads();
                    }

                    init();
                }
            };
        }
    ]);
}());

(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('userItems', ['$resource', 'urls',
        function($resource, metUrls) {

            var resource = $resource(
                metUrls('userItemsApi').concat('/:id'), {
                    id: '@id'
                }, {
                    restore: {
                        method: 'POST',
                        url: metUrls('userItemsApi').concat('/:id/restore'),
                        params: {
                            id: '@id'
                        }
                    },
                    'search': {
                        method: 'GET',
                        url: metUrls('userItemsApi').concat('/search')
                    },
                    history: {
                        method: 'GET',
                        url: metUrls('userItemsApi').concat('/history/:userItemId'),
                        params: {
                            userItemId: '@userItemId'
                        }
                    }
                }
            );

            return {
                get: function(userItemId, successCallback, errorCallback) {
                    return resource.get({
                            id: userItemId
                        },
                        successCallback,
                        errorCallback
                    );
                },
                update: function(userItem, successCallback, errorCallback) {
                    return resource.save(
                        userItem,
                        successCallback,
                        errorCallback
                    );
                },
                search: function(userItemFilters, successCallback, errorCallback) {
                    return resource.search(
                        userItemFilters,
                        successCallback,
                        errorCallback
                    );
                },
                create: function(userItem, successCallback, errorCallback) {
                    return resource.save(
                        userItem,
                        successCallback,
                        errorCallback
                    );
                },
                remove: function (itemId, successCallback, errorCallback) {
                    return resource.remove({
                        id: itemId
                        },
                        successCallback,
                        errorCallback
                    );
                },
                restore: function (itemId, successCallback, errorCallback) {
                    return resource.restore({
                        id: itemId
                        },
                        successCallback,
                        errorCallback
                    );
                },
                history: function (userItemId, successCallback, errorCallback) {
                    return resource.history({
                        userItemId: userItemId
                    },
                        successCallback,
                        errorCallback
                    );
                }
            };
        }
    ]);
}());
