From aef525a1e69a6f1e610f84315eddb4392f7a51eb Mon Sep 17 00:00:00 2001 From: MAhsenArif Date: Wed, 5 Sep 2018 12:41:49 +0500 Subject: [PATCH 1/7] [OPAL-560] Add further restriction based on cart product --- .../mno-app-install-btn.coffee | 21 +++++++++++++++++-- src/locales/en.json | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee b/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee index 56d6b272..15123585 100644 --- a/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee +++ b/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee @@ -7,6 +7,7 @@ angular.module 'mnoEnterpriseAngular' controller: ($q, $state, $window, $uibModal, toastr, MnoeMarketplace, MnoeProvisioning, MnoeCurrentUser, MnoeOrganizations, MnoeAppInstances, MnoeConfig, ProvisioningHelper) -> vm = this vm.orderPossible = true + vm.allowCartProductProvision = true vm.buttonText = '' vm.buttonDisabledTooltip = '' @@ -69,11 +70,13 @@ angular.module 'mnoEnterpriseAngular' vm.canProvisionApp = false vm.buttonDisabled = () -> - !vm.canProvisionApp || vm.appInstallationStatus() == "CONFLICT" || !vm.orderPossible + !vm.canProvisionApp || vm.appInstallationStatus() == "CONFLICT" || !vm.orderPossible || !vm.allowCartProductProvision vm.updateButtonDisabledTooltip = () -> if !vm.canProvisionApp 'mno_enterprise.templates.components.app_install_btn.insufficient_privilege' + else if !vm.allowCartProductProvision + 'mno_enterprise.templates.components.app_install_btn.cart_product' else if !vm.orderPossible 'mno_enterprise.templates.dashboard.marketplace.show.no_pricing_plans_found_tooltip' @@ -83,6 +86,9 @@ angular.module 'mnoEnterpriseAngular' else vm.appInstallationBtnText() + #==================================== + # UI Click Events + #==================================== vm.buttonClick = () -> if !vm.buttonDisabled() if vm.isExternallyProvisioned @@ -179,18 +185,21 @@ angular.module 'mnoEnterpriseAngular' # Retrieve the apps and the app instances in order to retrieve the current app, and its conflicting status # with the current installed app instances productPromise = if MnoeConfig.isProvisioningEnabled() then MnoeMarketplace.getProducts() else $q.resolve() + cartSubPromise = MnoeProvisioning.getSubscriptions({where: {subscription_status_in: 'staged'}}, true) $q.all( marketplace: MnoeMarketplace.getApps(), appInstances: MnoeAppInstances.getAppInstances(), currentUser: MnoeCurrentUser.get(), - products: productPromise + products: productPromise, + cartSubscriptions: cartSubPromise ).then( (response) -> apps = response.marketplace.apps appInstances = response.appInstances currentUser = response.currentUser products = response.products?.products + cartSubscriptions = response.cartSubscriptions currency = MnoeOrganizations.selected.organization.billing_currency || MnoeConfig.marketplaceCurrency() plans = vm.app.pricing_plans @@ -202,6 +211,14 @@ angular.module 'mnoEnterpriseAngular' organization = MnoeOrganizations.selected.organization vm.canProvisionApp = _.find(authorizedOrganizations, (org) -> org.id == organization.id) + # Check that the app is not already added to cart. If so, + # then prevent flow if the product is not multi instantiable + cartProducts = _.map(cartSubscriptions, (sub) -> sub?.product?.nid) + isCartProduct = vm.app.nid in cartProducts + vm.allowCartProductProvision = vm.app.multi_instantiable if isCartProduct + console.log 'vm.allowCartProductProvision' + console.log vm.allowCartProductProvision + # Find if the user already have an instance of it vm.appInstance = _.find(appInstances, {app_nid: vm.app.nid}) diff --git a/src/locales/en.json b/src/locales/en.json index ec80a1e5..d65c6fcc 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1049,6 +1049,7 @@ "mno_enterprise.templates.components.app_install_btn.access_addon": "Access Add-on", "mno_enterprise.templates.components.app_install_btn.access_addon_tooltip": "This application requires you to set-up the connection in a separate screen.", "mno_enterprise.templates.components.app_install_btn.insufficient_privilege": "You do not have the sufficient privileges. Contact your administrator.", + "mno_enterprise.templates.components.app_install_btn.cart_product": "Item is already added to Organization cart.", "mno_enterprise.templates.components.app_install_btn.success_notification_title": "{name} has been added to your account", "mno_enterprise.templates.components.app_install_btn.success_launch_notification_body": "To start using {name}, click on the {name} icon then click on \"Launch\".", "mno_enterprise.templates.components.app_install_btn.success_connect_notification_body": "To start using {name}, click on the {name} icon then click on \"Connect\".", From 57c0aa87a32eb728f5995260bd238096748d9189 Mon Sep 17 00:00:00 2001 From: MAhsenArif Date: Wed, 5 Sep 2018 12:42:44 +0500 Subject: [PATCH 2/7] [OPAL-560] Loader when submitting cart --- src/app/views/provisioning/subscriptions.controller.coffee | 4 ++++ src/app/views/provisioning/subscriptions.html | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/views/provisioning/subscriptions.controller.coffee b/src/app/views/provisioning/subscriptions.controller.coffee index fffaba98..a5daf05e 100644 --- a/src/app/views/provisioning/subscriptions.controller.coffee +++ b/src/app/views/provisioning/subscriptions.controller.coffee @@ -3,6 +3,7 @@ angular.module 'mnoEnterpriseAngular' vm = this vm.isLoading = true + vm.isCartSubmitting = false vm.cartSubscriptions = $stateParams.subType == 'cart' vm.skipPriceSelection = ProvisioningHelper.skipPriceSelection @@ -26,12 +27,15 @@ angular.module 'mnoEnterpriseAngular' ) vm.submitCart = -> + return if vm.isCartSubmitting + vm.isCartSubmitting = true MnoeProvisioning.submitCartSubscriptions().then( (response) -> # Reload dock apps MnoeProvisioning.refreshCartSubscriptions() toastr.success('mno_enterprise.templates.dashboard.provisioning.subscriptions.cart.submit_cart.toastr') + vm.isCartSubmitting = false $state.go("home.subscriptions", {subType: 'active'}) ) diff --git a/src/app/views/provisioning/subscriptions.html b/src/app/views/provisioning/subscriptions.html index dd80c39e..fd60f5e7 100644 --- a/src/app/views/provisioning/subscriptions.html +++ b/src/app/views/provisioning/subscriptions.html @@ -10,7 +10,8 @@

- From e337f9d0288ffd7814334e9320f547a6b2c8ab19 Mon Sep 17 00:00:00 2001 From: MAhsenArif Date: Wed, 5 Sep 2018 12:44:57 +0500 Subject: [PATCH 3/7] [OPAL-560] Reload app instances on cart submit --- src/app/views/provisioning/subscriptions.controller.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/views/provisioning/subscriptions.controller.coffee b/src/app/views/provisioning/subscriptions.controller.coffee index a5daf05e..bab6dc7e 100644 --- a/src/app/views/provisioning/subscriptions.controller.coffee +++ b/src/app/views/provisioning/subscriptions.controller.coffee @@ -1,5 +1,5 @@ angular.module 'mnoEnterpriseAngular' - .controller('ProvisioningSubscriptionsCtrl', ($q, $scope, $state, $stateParams, toastr, MnoeOrganizations, MnoeProvisioning, MnoeConfig, MnoConfirm, PRICING_TYPES, ProvisioningHelper) -> + .controller('ProvisioningSubscriptionsCtrl', ($q, $scope, $state, $stateParams, toastr, MnoeOrganizations, MnoeProvisioning, MnoeConfig, MnoConfirm, PRICING_TYPES, ProvisioningHelper, MnoeAppInstances, MnoeProductInstances) -> vm = this vm.isLoading = true @@ -33,6 +33,9 @@ angular.module 'mnoEnterpriseAngular' (response) -> # Reload dock apps MnoeProvisioning.refreshCartSubscriptions() + MnoeAppInstances.emptyAppInstances() + MnoeProductInstances.emptyProductInstances() + MnoeProductInstances.clearCache() toastr.success('mno_enterprise.templates.dashboard.provisioning.subscriptions.cart.submit_cart.toastr') vm.isCartSubmitting = false From fa5bf145fb722f832548f9d0e7baea3f1369258d Mon Sep 17 00:00:00 2001 From: MAhsenArif Date: Wed, 5 Sep 2018 12:46:45 +0500 Subject: [PATCH 4/7] [OPAL-560] Coffee lint error fix --- .../subscriptions.controller.coffee | 167 +++++++++--------- 1 file changed, 84 insertions(+), 83 deletions(-) diff --git a/src/app/views/provisioning/subscriptions.controller.coffee b/src/app/views/provisioning/subscriptions.controller.coffee index bab6dc7e..c8f73734 100644 --- a/src/app/views/provisioning/subscriptions.controller.coffee +++ b/src/app/views/provisioning/subscriptions.controller.coffee @@ -1,86 +1,87 @@ angular.module 'mnoEnterpriseAngular' - .controller('ProvisioningSubscriptionsCtrl', ($q, $scope, $state, $stateParams, toastr, MnoeOrganizations, MnoeProvisioning, MnoeConfig, MnoConfirm, PRICING_TYPES, ProvisioningHelper, MnoeAppInstances, MnoeProductInstances) -> - - vm = this - vm.isLoading = true - vm.isCartSubmitting = false - vm.cartSubscriptions = $stateParams.subType == 'cart' - vm.skipPriceSelection = ProvisioningHelper.skipPriceSelection - - vm.goToSubscription = (subscription) -> - ProvisioningHelper.goToSubscription(subscription, vm.cartSubscriptions) - - vm.subscriptionsPromise = -> - if vm.cartSubscriptions - params = { where: {subscription_status_in: 'staged' } } - MnoeProvisioning.getSubscriptions(params) - else - params = { where: {subscription_status_in: 'visible' } } - MnoeProvisioning.getSubscriptions(params) - - vm.deleteCart = -> - MnoeProvisioning.deleteCartSubscriptions().then( - (response) -> - MnoeProvisioning.emptyCartSubscriptions() - toastr.info('mno_enterprise.templates.dashboard.provisioning.subscriptions.cart.delete_cart.toastr') - $state.go("home.marketplace") - ) - - vm.submitCart = -> - return if vm.isCartSubmitting - vm.isCartSubmitting = true - MnoeProvisioning.submitCartSubscriptions().then( - (response) -> - # Reload dock apps - MnoeProvisioning.refreshCartSubscriptions() - MnoeAppInstances.emptyAppInstances() - MnoeProductInstances.emptyProductInstances() - MnoeProductInstances.clearCache() - - toastr.success('mno_enterprise.templates.dashboard.provisioning.subscriptions.cart.submit_cart.toastr') - vm.isCartSubmitting = false - $state.go("home.subscriptions", {subType: 'active'}) - ) - - vm.initialize = -> - vm.isLoading = true - orgPromise = MnoeOrganizations.get() - subPromise = vm.subscriptionsPromise() - - $q.all({organization: orgPromise, subscriptions: subPromise}).then( - (response) -> - vm.subscriptions = response.subscriptions - if vm.cartSubscriptions && vm.subscriptions.length < 1 - toastr.info('mno_enterprise.templates.dashboard.provisioning.subscriptions.cart.empty') - $state.go('home.marketplace') - return - - vm.orgCurrency = response.organization.organization?.billing_currency || MnoeConfig.marketplaceCurrency() - - # If a subscription doesn't contains a pricing for the org currency, a warning message is displayed - vm.displayCurrencyWarning = not _.every(response.subscriptions, (subscription) -> - currencies = _.map(subscription?.product_pricing?.prices, 'currency') - _.includes(currencies, vm.orgCurrency) || (subscription?.product_pricing?.pricing_type in PRICING_TYPES['unpriced']) - ) - ).finally(-> vm.isLoading = false) - - #==================================== - # Post-Initialization - #==================================== - $scope.$watch MnoeOrganizations.getSelectedId, (val) -> - vm.initialize() if val? + .controller('ProvisioningSubscriptionsCtrl', + ($q, $scope, $state, $stateParams, toastr, MnoeOrganizations, MnoeProvisioning, MnoeConfig, MnoConfirm, PRICING_TYPES, ProvisioningHelper, MnoeAppInstances, MnoeProductInstances) -> - vm.displayInfoTooltip = (subscription) -> - return subscription.status == 'aborted' - - vm.showEditAction = (subscription, editAction) -> - ProvisioningHelper.showEditAction(subscription, editAction) - - vm.editSubscription = (subscription, editAction) -> - ProvisioningHelper.editSubscription(subscription, editAction, vm.cartSubscriptions) - - vm.pendingSubscription = (subscription) -> - subscription.status in ['pending', 'provisioning'] - - return + vm = this + vm.isLoading = true + vm.isCartSubmitting = false + vm.cartSubscriptions = $stateParams.subType == 'cart' + vm.skipPriceSelection = ProvisioningHelper.skipPriceSelection + + vm.goToSubscription = (subscription) -> + ProvisioningHelper.goToSubscription(subscription, vm.cartSubscriptions) + + vm.subscriptionsPromise = -> + if vm.cartSubscriptions + params = { where: {subscription_status_in: 'staged' } } + MnoeProvisioning.getSubscriptions(params) + else + params = { where: {subscription_status_in: 'visible' } } + MnoeProvisioning.getSubscriptions(params) + + vm.deleteCart = -> + MnoeProvisioning.deleteCartSubscriptions().then( + (response) -> + MnoeProvisioning.emptyCartSubscriptions() + toastr.info('mno_enterprise.templates.dashboard.provisioning.subscriptions.cart.delete_cart.toastr') + $state.go("home.marketplace") + ) + + vm.submitCart = -> + return if vm.isCartSubmitting + vm.isCartSubmitting = true + MnoeProvisioning.submitCartSubscriptions().then( + (response) -> + # Reload dock apps + MnoeProvisioning.refreshCartSubscriptions() + MnoeAppInstances.emptyAppInstances() + MnoeProductInstances.emptyProductInstances() + MnoeProductInstances.clearCache() + + toastr.success('mno_enterprise.templates.dashboard.provisioning.subscriptions.cart.submit_cart.toastr') + vm.isCartSubmitting = false + $state.go("home.subscriptions", {subType: 'active'}) + ) + + vm.initialize = -> + vm.isLoading = true + orgPromise = MnoeOrganizations.get() + subPromise = vm.subscriptionsPromise() + + $q.all({organization: orgPromise, subscriptions: subPromise}).then( + (response) -> + vm.subscriptions = response.subscriptions + if vm.cartSubscriptions && vm.subscriptions.length < 1 + toastr.info('mno_enterprise.templates.dashboard.provisioning.subscriptions.cart.empty') + $state.go('home.marketplace') + return + + vm.orgCurrency = response.organization.organization?.billing_currency || MnoeConfig.marketplaceCurrency() + + # If a subscription doesn't contains a pricing for the org currency, a warning message is displayed + vm.displayCurrencyWarning = not _.every(response.subscriptions, (subscription) -> + currencies = _.map(subscription?.product_pricing?.prices, 'currency') + _.includes(currencies, vm.orgCurrency) || (subscription?.product_pricing?.pricing_type in PRICING_TYPES['unpriced']) + ) + ).finally(-> vm.isLoading = false) + + #==================================== + # Post-Initialization + #==================================== + $scope.$watch MnoeOrganizations.getSelectedId, (val) -> + vm.initialize() if val? + + vm.displayInfoTooltip = (subscription) -> + return subscription.status == 'aborted' + + vm.showEditAction = (subscription, editAction) -> + ProvisioningHelper.showEditAction(subscription, editAction) + + vm.editSubscription = (subscription, editAction) -> + ProvisioningHelper.editSubscription(subscription, editAction, vm.cartSubscriptions) + + vm.pendingSubscription = (subscription) -> + subscription.status in ['pending', 'provisioning'] + + return ) From 87204b9d6a1df4d26886373058c409cefc0da4ce Mon Sep 17 00:00:00 2001 From: MAhsenArif Date: Wed, 5 Sep 2018 12:57:35 +0500 Subject: [PATCH 5/7] [OPAL-560] Delete cart should also have a loder --- src/app/views/provisioning/subscriptions.controller.coffee | 6 +++++- src/app/views/provisioning/subscriptions.html | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/app/views/provisioning/subscriptions.controller.coffee b/src/app/views/provisioning/subscriptions.controller.coffee index c8f73734..a3be29d3 100644 --- a/src/app/views/provisioning/subscriptions.controller.coffee +++ b/src/app/views/provisioning/subscriptions.controller.coffee @@ -5,6 +5,7 @@ angular.module 'mnoEnterpriseAngular' vm = this vm.isLoading = true vm.isCartSubmitting = false + vm.isCartDeleting = false vm.cartSubscriptions = $stateParams.subType == 'cart' vm.skipPriceSelection = ProvisioningHelper.skipPriceSelection @@ -20,15 +21,18 @@ angular.module 'mnoEnterpriseAngular' MnoeProvisioning.getSubscriptions(params) vm.deleteCart = -> + return if vm.isCartSubmitting || vm.isCartDeleting + vm.isCartDeleting = true MnoeProvisioning.deleteCartSubscriptions().then( (response) -> MnoeProvisioning.emptyCartSubscriptions() toastr.info('mno_enterprise.templates.dashboard.provisioning.subscriptions.cart.delete_cart.toastr') + vm.isCartDeleting = false $state.go("home.marketplace") ) vm.submitCart = -> - return if vm.isCartSubmitting + return if vm.isCartSubmitting || vm.isCartDeleting vm.isCartSubmitting = true MnoeProvisioning.submitCartSubscriptions().then( (response) -> diff --git a/src/app/views/provisioning/subscriptions.html b/src/app/views/provisioning/subscriptions.html index fd60f5e7..b5f3769c 100644 --- a/src/app/views/provisioning/subscriptions.html +++ b/src/app/views/provisioning/subscriptions.html @@ -7,10 +7,11 @@

- - From 0085ebe7ad266aa2ac566328ae2145f40cf7a694 Mon Sep 17 00:00:00 2001 From: MAhsenArif Date: Wed, 5 Sep 2018 13:20:19 +0500 Subject: [PATCH 6/7] [OPAL-560] Cleanup --- .../mno-app-install-btn/mno-app-install-btn.coffee | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee b/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee index 15123585..ec6fb0ad 100644 --- a/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee +++ b/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee @@ -86,9 +86,6 @@ angular.module 'mnoEnterpriseAngular' else vm.appInstallationBtnText() - #==================================== - # UI Click Events - #==================================== vm.buttonClick = () -> if !vm.buttonDisabled() if vm.isExternallyProvisioned @@ -211,13 +208,11 @@ angular.module 'mnoEnterpriseAngular' organization = MnoeOrganizations.selected.organization vm.canProvisionApp = _.find(authorizedOrganizations, (org) -> org.id == organization.id) - # Check that the app is not already added to cart. If so, - # then prevent flow if the product is not multi instantiable + # Check that the app/product is not already added to cart. If so, + # then prevent flow if the app/product is not multi instantiable cartProducts = _.map(cartSubscriptions, (sub) -> sub?.product?.nid) isCartProduct = vm.app.nid in cartProducts vm.allowCartProductProvision = vm.app.multi_instantiable if isCartProduct - console.log 'vm.allowCartProductProvision' - console.log vm.allowCartProductProvision # Find if the user already have an instance of it vm.appInstance = _.find(appInstances, {app_nid: vm.app.nid}) From a32b8ede5f0b9ac0178f4ce800b88f52ce7390d1 Mon Sep 17 00:00:00 2001 From: MAhsenArif Date: Wed, 5 Sep 2018 15:50:16 +0500 Subject: [PATCH 7/7] [OPAL-560] Handle cart subscription request crashing for member users --- .../mno-app-install-btn.coffee | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee b/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee index ec6fb0ad..549546a9 100644 --- a/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee +++ b/src/app/components/mno-app-install-btn/mno-app-install-btn.coffee @@ -182,21 +182,18 @@ angular.module 'mnoEnterpriseAngular' # Retrieve the apps and the app instances in order to retrieve the current app, and its conflicting status # with the current installed app instances productPromise = if MnoeConfig.isProvisioningEnabled() then MnoeMarketplace.getProducts() else $q.resolve() - cartSubPromise = MnoeProvisioning.getSubscriptions({where: {subscription_status_in: 'staged'}}, true) $q.all( marketplace: MnoeMarketplace.getApps(), appInstances: MnoeAppInstances.getAppInstances(), currentUser: MnoeCurrentUser.get(), - products: productPromise, - cartSubscriptions: cartSubPromise + products: productPromise ).then( (response) -> apps = response.marketplace.apps appInstances = response.appInstances currentUser = response.currentUser products = response.products?.products - cartSubscriptions = response.cartSubscriptions currency = MnoeOrganizations.selected.organization.billing_currency || MnoeConfig.marketplaceCurrency() plans = vm.app.pricing_plans @@ -208,12 +205,6 @@ angular.module 'mnoEnterpriseAngular' organization = MnoeOrganizations.selected.organization vm.canProvisionApp = _.find(authorizedOrganizations, (org) -> org.id == organization.id) - # Check that the app/product is not already added to cart. If so, - # then prevent flow if the app/product is not multi instantiable - cartProducts = _.map(cartSubscriptions, (sub) -> sub?.product?.nid) - isCartProduct = vm.app.nid in cartProducts - vm.allowCartProductProvision = vm.app.multi_instantiable if isCartProduct - # Find if the user already have an instance of it vm.appInstance = _.find(appInstances, {app_nid: vm.app.nid}) @@ -246,6 +237,18 @@ angular.module 'mnoEnterpriseAngular' vm.orderPossible = !_.isEmpty(availablePlans) || (plans.default?[0] && currencySelection) || ProvisioningHelper.skipPriceSelection(product) + # For Admins, check that the app/product is not already added to cart. + # If so, then prevent flow if the app/product is not multi instantiable + if vm.canProvisionApp + params = {where: {subscription_status_in: 'staged'}} + MnoeProvisioning.getSubscriptions(params, true).then( + (resp) -> + cartProducts = _.map(resp, (sub) -> sub?.product?.nid) + isCartProduct = vm.app.nid in cartProducts + vm.allowCartProductProvision = vm.app.multi_instantiable if isCartProduct + ) + ).finally( + -> vm.buttonText = vm.updateButtonText() vm.buttonDisabledTooltip = vm.updateButtonDisabledTooltip() )