From 789c6a28fe35f7a9f59516837001b6e15318784c Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 9 Nov 2020 16:54:20 +0100 Subject: [PATCH] handle subscription creation only from the cart --- .../src/javascript/directives/cart.js | 32 +++++++++++++++---- .../src/javascript/directives/stripe-form.js | 16 +++++----- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/app/frontend/src/javascript/directives/cart.js b/app/frontend/src/javascript/directives/cart.js index 6d492014b..f2e692613 100644 --- a/app/frontend/src/javascript/directives/cart.js +++ b/app/frontend/src/javascript/directives/cart.js @@ -621,7 +621,7 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs', * @param member {Object} User as retrieved from the API: current user / selected user if current is admin * @param slots {Array} Array of fullCalendar events: slots selected on the calendar * @param [plan] {Object} Plan as retrieved from the API: plan to buy with the current reservation - * @return {{user_id:Number, reservable_id:Number, reservable_type:String, slots_attributes:Array, plan_id:Number|null}} + * @return {{reservable_type: string, payment_schedule: boolean, user_id: *, reservable_id: string, slots_attributes: [], plan_id: (*|undefined)}} */ const mkReservation = function (member, slots, plan) { const reservation = { @@ -727,10 +727,13 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs', }, selectedPlan () { return $scope.selectedPlan; + }, + schedule () { + return $scope.schedule.requested_schedule; } }, - controller: ['$scope', '$uibModalInstance', '$state', 'reservation', 'price', 'Auth', 'Reservation', 'wallet', 'helpers', '$filter', 'coupon', 'selectedPlan', - function ($scope, $uibModalInstance, $state, reservation, price, Auth, Reservation, wallet, helpers, $filter, coupon, selectedPlan) { + controller: ['$scope', '$uibModalInstance', '$state', 'reservation', 'price', 'Auth', 'Reservation', 'Subscription', 'wallet', 'helpers', '$filter', 'coupon', 'selectedPlan', 'schedule', + function ($scope, $uibModalInstance, $state, reservation, price, Auth, Reservation, Subscription, wallet, helpers, $filter, coupon, selectedPlan, schedule) { // user wallet amount $scope.walletAmount = wallet.amount; @@ -749,6 +752,9 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs', // Used in wallet info template to interpolate some translations $scope.numberFilter = $filter('number'); + // TODO, show the schedule info in the modal + $scope.schedule = schedule; + // Button label if ($scope.amount > 0) { $scope.validButtonName = _t('app.shared.cart.confirm_payment_of_html', { ROLE: $rootScope.currentUser.role, AMOUNT: $filter('currency')($scope.amount) }); @@ -765,11 +771,24 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs', */ $scope.ok = function () { $scope.attempting = true; - return Reservation.save(mkRequestParams($scope.reservation, coupon), function (reservation) { + // save subscription (if there's only a subscription selected) + if (reservation.slots_attributes.length === 0 && selectedPlan) { + return Subscription.save({ + coupon_code: ((coupon ? coupon.code : undefined)), + subscription: { + plan_id: selectedPlan.id, + user_id: reservation.user_id, + payment_schedule: schedule // TODO, check it is the best place to pass the param + } + }, function () { + // TODO, then... and error handling + }); + } + // otherwise, save the reservation (may include a subscription) + Reservation.save(mkRequestParams($scope.reservation, coupon), function (reservation) { $uibModalInstance.close(reservation); return $scope.attempting = true; - } - , function (response) { + }, function (response) { $scope.alerts = []; $scope.alerts.push({ msg: _t('app.shared.cart.a_problem_occurred_during_the_payment_process_please_try_again_later'), type: 'danger' }); return $scope.attempting = false; @@ -780,6 +799,7 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs', ] }).result.finally(null).then(function (reservation) { afterPayment(reservation); }); }; + /** * Actions to run after the payment was successful */ diff --git a/app/frontend/src/javascript/directives/stripe-form.js b/app/frontend/src/javascript/directives/stripe-form.js index 5aa8c7ee4..cd0929cff 100644 --- a/app/frontend/src/javascript/directives/stripe-form.js +++ b/app/frontend/src/javascript/directives/stripe-form.js @@ -15,7 +15,7 @@ Application.Directives.directive('stripeForm', ['Payment', 'growl', '_t', onPaymentSuccess: '=', stripeKey: '@' }, - link: function($scope, element, attributes) { + link: function ($scope, element, attributes) { const stripe = Stripe($scope.stripeKey); const elements = stripe.elements(); @@ -51,11 +51,11 @@ Application.Directives.directive('stripeForm', ['Payment', 'growl', '_t', const cardElement = form.find('#card-element'); card.mount(cardElement[0]); - form.bind('submit', function() { + form.bind('submit', function () { const button = form.find('button'); button.prop('disabled', true); - stripe.createPaymentMethod('card', card).then(function({ paymentMethod, error }) { + stripe.createPaymentMethod('card', card).then(function ({ paymentMethod, error }) { if (error) { growl.error(error.message); button.prop('disabled', false); @@ -64,12 +64,12 @@ Application.Directives.directive('stripeForm', ['Payment', 'growl', '_t', Payment.confirm({ payment_method_id: paymentMethod.id, cart_items: $scope.cartItems }, function (response) { // Handle server response (see Step 3) handleServerResponse(response, button); - }, function(error) { handleServerResponse({ error }, button) }); + }, function (error) { handleServerResponse({ error }, button); }); } }); }); - function handleServerResponse(response, confirmButton) { + function handleServerResponse (response, confirmButton) { if (response.error) { if (response.error.statusText) { growl.error(response.error.statusText); @@ -81,16 +81,16 @@ Application.Directives.directive('stripeForm', ['Payment', 'growl', '_t', // Use Stripe.js to handle required card action stripe.handleCardAction( response.payment_intent_client_secret - ).then(function(result) { + ).then(function (result) { if (result.error) { growl.error(result.error.message); confirmButton.prop('disabled', false); } else { // The card action has been handled // The PaymentIntent can be confirmed again on the server - Payment.confirm({ payment_intent_id: result.paymentIntent.id, cart_items: $scope.cartItems }, function(confirmResult) { + Payment.confirm({ payment_intent_id: result.paymentIntent.id, cart_items: $scope.cartItems }, function (confirmResult) { handleServerResponse(confirmResult, confirmButton); - }, function(error) { handleServerResponse({ error }, confirmButton) }); + }, function (error) { handleServerResponse({ error }, confirmButton); }); } }); } else {