From 9d7440e241c3f34ae1af1df44c03347b97af3307 Mon Sep 17 00:00:00 2001
From: Olivier Brisse <olivier.brisse@maestrano.com>
Date: Fri, 14 Oct 2016 17:14:55 +1100
Subject: [PATCH] [MNOE-217] Fix app page

App page was broken if the user had an app that was no longer available
on the marketplace.
Also refactored the code.
---
 .../marketplace-app.controller.coffee         | 50 +++++++++++--------
 .../views/marketplace/marketplace-app.html    |  2 +-
 2 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/src/app/views/marketplace/marketplace-app.controller.coffee b/src/app/views/marketplace/marketplace-app.controller.coffee
index 0b18cfee..9f3e0584 100644
--- a/src/app/views/marketplace/marketplace-app.controller.coffee
+++ b/src/app/views/marketplace/marketplace-app.controller.coffee
@@ -14,16 +14,16 @@ angular.module 'mnoEnterpriseAngular'
       vm.app = {}
       # The already installed app instance of the app, if any
       vm.appInstance = null
-      # An already installed app instance, conflicting with the app because it contains a common subcategory
+      # An already installed app, conflicting with the app because it contains a common subcategory
       # that is not multi instantiable, if any
-      vm.conflictingAppInstance = null
+      vm.conflictingApp = null
       #====================================
       # Scope Management
       #====================================
-      vm.initialize = (app, appInstance, conflictingAppInstance) ->
+      vm.initialize = (app, appInstance, conflictingApp) ->
         angular.copy(app, vm.app)
         vm.appInstance = appInstance
-        vm.conflictingAppInstance = conflictingAppInstance
+        vm.conflictingApp = conflictingApp
         vm.app.description = $sce.trustAsHtml(app.description)
         vm.isLoading = false
         plans = vm.app.pricing_plans
@@ -45,7 +45,7 @@ angular.module 'mnoEnterpriseAngular'
           else
             "INSTALLED"
         else
-          if vm.conflictingAppInstance
+          if vm.conflictingApp
             "CONFLICT"
           else
             "INSTALLABLE"
@@ -83,30 +83,40 @@ angular.module 'mnoEnterpriseAngular'
           vm.isLoading = true
           # Retrieve the apps and the app instances in order to retrieve the current app, and its conflicting status
           # with the current installed app instances
-          $q.all([MnoeMarketplace.getApps(), MnoeAppInstances.getAppInstances()]).then(
+          $q.all(
+            marketplace: MnoeMarketplace.getApps(),
+            appInstances: MnoeAppInstances.getAppInstances()
+          ).then(
             (response)->
-              apps = response[0].apps
-              appInstances = response[1]
-              appId = parseInt($stateParams.appId)
-              appsPerNid = {}
-              appsPerNid[a.nid] = a for a in apps
+              apps = response.marketplace.apps
+              appInstances = response.appInstances
 
-              app = _.findWhere(apps, { slug: $stateParams.appId })
+              # App to be added
+              appId = parseInt($stateParams.appId)
+              app = _.findWhere(apps, { nid: $stateParams.appId })
               app ||= _.findWhere(apps, { id:  appId})
+
+              # Find if we already have it
               appInstance = _.find(appInstances, { app_nid: app.nid})
-              # Find conflicting app instance with the current app based on the subcategories
-              # If there is already an insalled app instance, with a common subcategory with the app that is not multi_instantiable
-              # We keep that appInstance, as a conflictingAppInstance, to explain why the app cannot be installed.
+
+              # Get the list of installed Apps
+              nids = _.compact(_.map(appInstances, (a) -> a.app_nid))
+              installedApps = _.filter(apps, (a) -> a.nid in nids)
+
+              # Find conflicting app with the current app based on the subcategories
+              # If there is already an installed app, with a common subcategory with the app that is not multi_instantiable
+              # We keep that app, as a conflictingApp, to explain why the app cannot be installed.
               if app.subcategories
                 # retrieve the subcategories names
-                names = app.subcategories.map (c) -> c.name
-                conflictingAppInstance = _.find(appInstances, (appInst) ->
-                  appInstanceApp = appsPerNid[appInst.app_nid]
-                  _.find(appInstanceApp.subcategories, (subCategory) ->
+                names = _.map(app.subcategories, 'name')
+
+                conflictingApp = _.find(installedApps, (app) ->
+                  _.find(app.subcategories, (subCategory) ->
                     not subCategory.multi_instantiable and subCategory.name in names
                   )
                 )
-              vm.initialize(app, appInstance, conflictingAppInstance)
+
+              vm.initialize(app, appInstance, conflictingApp)
           )
 
       return
diff --git a/src/app/views/marketplace/marketplace-app.html b/src/app/views/marketplace/marketplace-app.html
index 4c2cd5f2..07be5219 100644
--- a/src/app/views/marketplace/marketplace-app.html
+++ b/src/app/views/marketplace/marketplace-app.html
@@ -41,7 +41,7 @@ <h2 class="media-heading">{{vm.app.name}}</h2>
                     <div ng-switch-when="CONFLICT" class="message">
                       <i class="fa fa-exclamation-triangle"></i>
                       {{ 'mno_enterprise.templates.dashboard.marketplace.show.conflicting_app' | translate }}
-                      <a ui-sref="home.marketplace.app({appId: vm.conflictingAppInstance.app_id})">{{vm.conflictingAppInstance.app_name}}</a>
+                      <a ui-sref="home.marketplace.app({appId: vm.conflictingApp.id})">{{vm.conflictingApp.name}}</a>
                     </div>
                     <a href="" ng-switch-when="INSTALLABLE" ng-click="vm.provisionLink()" class="btn btn-warning btn-promo">
                       {{ 'mno_enterprise.templates.dashboard.marketplace.show.start_app' | translate }}