Source: services/menuCamada.js

    /**
     * @ngdoc service
     * @name MenuCamada
     * @module s4c.services.MenuCamada
     * 
     * @description  Componente para acesso a api do backend e/ou comunicação entre controllers
     * 
     *
     */
     
(function () {
    angular
        .module('s4c.services')
        .factory('Menu', Menu);

    Menu.$inject = ['Base', '$q'];

   /**	
	* @method Menu
	* @param {*} Base
	* @param {*} $q
	*/
    function Menu(Base, $q) {
        var service = {
            obter: obter,
            obterGeoJSON: obterGeoJSON,
            clearPromise: clearPromise
        };
        var promises = [];
        var grupoIds = [];

  	   /**	
		* @method _obterSubMenus
		* @param {*} menu
		*/
        function _obterSubMenus(menu) {

            _.each(menu.subMenus, function (subMenu) {
                _obterSubMenus(subMenu)
            });

            if (menu.GrupoId) {

                var deferred = $q.defer();

                grupoIds.push(menu.GrupoId);

            } else if (menu.urlSubMenus) {

                var deferred = $q.defer();

                Base
                    .obter(menu.urlSubMenus, null, menu.headers)
                    .then(function (subMenus) {

                        menu.subMenus = _.sortBy(menu.subMenus.concat(subMenus), 'texto');

                        deferred.resolve();
                    });

                promises.push(deferred.promise);

            }
        }

        var self = this;
        self.promise = undefined;
        var canLoad = true;

  	   /**	
		* @method obter
		* @param {*} reloadFromServer
		*/
        function obter(reloadFromServer) {

            canLoad = true;

            if (!reloadFromServer && (self.promise || !canLoad)) {
                return self.promise;
            }

            var deferred = $q.defer();

            canLoad = false;
            Base
                .obter('menuCamada')
                .then(function (menus) {

                    _.each(menus, function (menu) {
                        _obterSubMenus(menu)
                    });

                    if (grupoIds.length > 0) {
                        Base
                            .obter('menuCamada/grupo/lista/', { filtro: { grupoIds } })
                            .then(function (subMenus) {

                                _.each(menus, function (menu) {
                                    _.each(subMenus, function (subMenu) {
                                        if (menu.GrupoId == subMenu.grupoId) {
                                            menu.subMenus = _.sortBy(menu.subMenus.concat(subMenu), 'texto');
                                        }
                                    })
                                });

                                $q.all(promises).then(function () {
                                    deferred.resolve(menus);
                                    canLoad = true;
                                });
                            });

                        return;
                    }

                    $q.all(promises).then(function () {
                        deferred.resolve(menus);
                        canLoad = true;
                    });
                });

            self.promise = deferred.promise;
            return self.promise;
        }

  	   /**	
		* @method clearPromise
		*/
        function clearPromise() {
            self.promise = undefined;
        }

  	   /**	
		* @method obterGeoJSON
		* @param {*} url
		*/
        function obterGeoJSON(url) {
            return Base.obter(url);
        }

        return service;
    }
}());