text:     /**
       * @ngdoc controller
       * @name Merchello.Backoffice.CustomerOverviewController
       * @function
       *
       * @description
       * The controller for customer overview view
       */
      angular.module('merchello').controller('Merchello.Backoffice.CustomerOverviewController',
          ['$scope', '$routeParams', '$timeout', 'dialogService', 'notificationsService', 'gravatarService', 'settingsResource', 'invoiceHelper', 'merchelloTabsFactory', 'dialogDataFactory',
              'customerResource', 'customerDisplayBuilder', 'countryDisplayBuilder', 'currencyDisplayBuilder', 'settingDisplayBuilder',
          function($scope, $routeParams, $timeout, dialogService, notificationsService, gravatarService, settingsResource, invoiceHelper, merchelloTabsFactory, dialogDataFactory,
                   customerResource, customerDisplayBuilder, countryDisplayBuilder, currencyDisplayBuilder, settingDisplayBuilder) {
  
              $scope.loaded = false;
              $scope.preValuesLoaded = false;
              $scope.tabs = [];
              $scope.avatarUrl = "";
              $scope.defaultShippingAddress = {};
              $scope.defaultBillingAddress = {};
              $scope.customer = {};
              $scope.invoiceTotals = [];
  
              // exposed methods
              $scope.getCurrency = getCurrency;
              $scope.openEditInfoDialog = openEditInfoDialog;
              $scope.openDeleteCustomerDialog = openDeleteCustomerDialog;
              $scope.openAddressAddEditDialog = openAddressAddEditDialog;
              $scope.saveCustomer = saveCustomer;
  
              // private properties
              var settings = {};
              var defaultCurrency = {};
              var countries = [];
              var currencies = [];
  
              /**
               * @ngdoc method
               * @name init
               * @function
               *
               * @description
               * Inititalizes the scope.
               */
              function init() {
                  var key = $routeParams.id;
                  loadSettings();
                  loadCustomer(key);
              }
  
              /**
               * @ngdoc method
               * @name loadCustomer
               * @function
               *
               * @description
               * Load the customer information if needed.
               */
              function loadCustomer(key) {
                  var promiseLoadCustomer = customerResource.GetCustomer(key);
                  promiseLoadCustomer.then(function(customerResponse) {
                      $scope.customer = customerDisplayBuilder.transform(customerResponse);
                      $scope.invoiceTotals = invoiceHelper.getTotalsByCurrencyCode($scope.customer.invoices);
                      $scope.avatarUrl = gravatarService.getAvatarUrl($scope.customer.email);
                      $scope.defaultBillingAddress = $scope.customer.getDefaultBillingAddress();
                      $scope.defaultShippingAddress = $scope.customer.getDefaultShippingAddress();
                      $scope.tabs = merchelloTabsFactory.createCustomerOverviewTabs(key, $scope.customer.hasAddresses());
                      $scope.tabs.setActive('overview');
                      $scope.loaded = true;
                      $scope.preValuesLoaded = true;
                      console.info($scope.customer);
                  }, function(reason) {
                      notificationsService.error("Failed to load customer", reason.message);
                  });
              }
  
              /**
               * @ngdoc method
               * @name loadCountries
               * @function
               *
               * @description
               * Load a list of countries and provinces from the API.
               */
              function loadSettings() {
                  // gets all of the countries
                  var promiseCountries = settingsResource.getAllCountries();
                  promiseCountries.then(function(countriesResponse) {
                      countries = countryDisplayBuilder.transform(countriesResponse);
                  });
  
                  // gets all of the settings
                  var promiseSettings = settingsResource.getAllSettings();
                  promiseSettings.then(function(settingsResponse) {
                      settings = settingDisplayBuilder.transform(settingsResponse);
  
                      // we need all of the currencies since invoices may be billed in various currencies
                      var promiseCurrencies = settingsResource.getAllCurrencies();
                      promiseCurrencies.then(function(currenciesResponse) {
                          currencies = currencyDisplayBuilder.transform(currenciesResponse);
  
                          // get the default currency from the settings in case we cannot determine
                          // the currency used in an invoice
                          defaultCurrency = _.find(currencies, function(c) {
                              return c.currencyCode === settings.currencyCode;
                          });
                      });
                  });
              }
  
              /**
               * @ngdoc method
               * @name openAddressEditDialog
               * @function
               *
               * @description
               * Opens the edit address dialog via the Umbraco dialogService.
               */
              function openAddressAddEditDialog(address) {
                  var dialogData = dialogDataFactory.createAddEditCustomerAddressDialogData();
                  // if the address is not defined we need to create a default (empty) CustomerAddressDisplay
                  if(address === null || address === undefined) {
                      dialogData.customerAddress = customerAddressDisplayBuilder.createDefault();
                      dialogData.selectedCountry = countries[0];
                  } else {
                      dialogData.customerAddress = address;
                      dialogData.selectedCountry = address.countryCode === '' ? countries[0] :
                          _.find(countries, function(country) {
                          return country.countryCode === address.countryCode;
                      });
                  }
                  dialogData.countries = countries;
                  dialogData.customerAddress.customerKey = $scope.customer.key;
                  if (dialogData.selectedCountry.hasProvinces()) {
                      if(dialogData.customerAddress.region !== '') {
                          dialogData.selectedProvince = _.find(dialogData.selectedCountry.provinces, function(province) {
                              return province.code === address.region;
                          });
                      }
                      if(dialogData.selectedProvince === null || dialogData.selectedProvince === undefined) {
                          dialogData.selectedProvince = dialogData.selectedCountry.provinces[0];
                      }
                  }
                  // if the customer has not addresses of the given type we are going to force an added
                  // address to be the primary address
                  if(!$scope.customer.hasDefaultAddressOfType(dialogData.customerAddress.addressType) || address.isDefault) {
                      dialogData.customerAddress.isDefault = true;
                      dialogData.setDefault = true;
                  }
                  dialogService.open({
                      template: '/App_Plugins/Merchello/Backoffice/Merchello/Dialogs/customer.customeraddress.addedit.html',
                      show: true,
                      callback: processAddEditAddressDialog,
                      dialogData: dialogData
                  });
              }
  
              /**
               * @ngdoc method
               * @name openDeleteCustomerDialog
               * @function
               *
               * @description
               * Opens the delete customer dialog via the Umbraco dialogService.
               */
              function openDeleteCustomerDialog() {
                  var dialogData = dialogDataFactory.createDeleteCustomerDialogData();
                  dialogData.customer = $scope.customer;
                  dialogData.name = $scope.customer.firstName + ' ' + $scope.customer.lastName;
                  dialogService.open({
                      template: '/App_Plugins/Merchello/Backoffice/Merchello/Dialogs/delete.confirmation.html',
                      show: true,
                      callback: processDeleteCustomerDialog,
                      dialogData: dialogData
                  });
              }
  
              /**
               * @ngdoc method
               * @name openEditInfoDialog
               * @function
               *
               * @description
               * Opens the edit customer info dialog via the Umbraco dialogService.
               */
              function openEditInfoDialog() {
  
                  var dialogData = dialogDataFactory.createAddEditCustomerDialogData();
                  dialogData.firstName = $scope.customer.firstName;
                  dialogData.lastName = $scope.customer.lastName;
                  dialogData.email = $scope.customer.email;
  
                  dialogService.open({
                      template: '/App_Plugins/Merchello/Backoffice/Merchello/Dialogs/customer.info.addedit.html',
                      show: true,
                      callback: processEditInfoDialog,
                      dialogData: dialogData
                  });
              }
  
  
              /**
               * @ngdoc method
               * @name processEditAddressDialog
               * @function
               *
               * @description
               * Edit an address and update the associated lists.
               */
              function processAddEditAddressDialog(dialogData) {
                  var defaultAddressOfType = $scope.customer.getDefaultAddress(dialogData.customerAddress.addressType);
                  if(dialogData.customerAddress.key !== '') {
                      $scope.customer.addresses =_.reject($scope.customer.addresses, function(address) {
                        return address.key == dialogData.customerAddress.key;
                      });
                  }
                  if (dialogData.customerAddress.isDefault && defaultAddressOfType !== undefined) {
                      if(dialogData.customerAddress.key !== defaultAddressOfType.key) {
                          defaultAddressOfType.isDefault = false;
                      }
                  }
                  $scope.customer.addresses.push(dialogData.customerAddress);
                  saveCustomer();
              }
  
              /**
               * @ngdoc method
               * @name processDeleteCustomerDialog
               * @function
               *
               * @description
               * Delete a customer.
               */
              function processDeleteCustomerDialog(dialogData) {
                  notificationsService.info("Deleting " + dialogData.customer.firstName + " " + dialogData.customer.lastName, "");
                  var promiseDeleteCustomer = customerResource.DeleteCustomer(dialogData.customer.key);
                  promiseDeleteCustomer.then(function() {
                      notificationsService.success("Customer deleted.", "");
                      window.location.hash = "#/merchello/merchello/customerList/manage";
                  }, function(reason) {
                      notificationsService.error("Customer Deletion Failed", reason.message);
                  });
              }
  
              /**
               * @ngdoc method
               * @name processEditInfoDialog
               * @function
               *
               * @description
               * Update the customer info and save.
               */
              function processEditInfoDialog(dialogData) {
                  $scope.customer.firstName = dialogData.firstName;
                  $scope.customer.lastName = dialogData.lastName;
                  $scope.customer.email = dialogData.email;
                  saveCustomer();
              }
  
              /**
               * @ngdoc method
               * @name saveCustomer
               * @function
               *
               * @description
               * Save the customer with the new note.
               */
              function saveCustomer() {
                  $scope.preValuesLoaded = false;
                  notificationsService.info("Saving...", "");
                  var promiseSaveCustomer = customerResource.SaveCustomer($scope.customer);
                  promiseSaveCustomer.then(function(customerResponse) {
                      $timeout(function() {
                      notificationsService.success("Customer Saved", "");
                          loadCustomer($scope.customer.key);
                      }, 400);
  
                  }, function(reason) {
                      notificationsService.error("Customer  Failed", reason.message);
                  });
              }
  
              /**
               * @ngdoc method
               * @name getCurrencySymbol
               * @function
               *
               * @description
               * Gets the currency symbol for an invoice.
               */
              function getCurrency(currencyCode) {
                  var currency = _.find(currencies, function(c) {
                      return c.currencyCode === currencyCode;
                  });
                  if (currency === null || currency === undefined) {
                      currency = defaultCurrency;
                  }
                  return currency;
              }
  
              // Initializes the controller
              init();
      }]);
  