diff --git a/app/controllers/api/payment_schedules_controller.rb b/app/controllers/api/payment_schedules_controller.rb index e943ffb81..a89d839e0 100644 --- a/app/controllers/api/payment_schedules_controller.rb +++ b/app/controllers/api/payment_schedules_controller.rb @@ -55,13 +55,13 @@ class API::PaymentSchedulesController < API::ApiController authorize @payment_schedule_item.payment_schedule # FIXME stripe_key = Setting.get('stripe_secret_key') - stp_invoice = Stripe::Invoice.pay(@payment_schedule_item.stp_invoice_id, {}, { api_key: stripe_key }) + stp_invoice = Stripe::Invoice.pay(@payment_schedule_item.payment_gateway_object.gateway_object_id, {}, { api_key: stripe_key }) PaymentScheduleItemWorker.new.perform(@payment_schedule_item.id) render json: { status: stp_invoice.status }, status: :ok rescue Stripe::StripeError => e stripe_key = Setting.get('stripe_secret_key') - stp_invoice = Stripe::Invoice.retrieve(@payment_schedule_item.stp_invoice_id, api_key: stripe_key) + stp_invoice = Stripe::Invoice.retrieve(@payment_schedule_item.payment_gateway_object.gateway_object_id, api_key: stripe_key) PaymentScheduleItemWorker.new.perform(@payment_schedule_item.id) render json: { status: stp_invoice.status, error: e }, status: :unprocessable_entity diff --git a/app/controllers/api/reservations_controller.rb b/app/controllers/api/reservations_controller.rb index a240a8e66..0e2459014 100644 --- a/app/controllers/api/reservations_controller.rb +++ b/app/controllers/api/reservations_controller.rb @@ -28,8 +28,8 @@ class API::ReservationsController < API::ApiController # otherwise, they must use payments_controller#confirm_payment. # Managers can create reservations for other users def create - user_id = current_user.admin? || current_user.manager? ? params[:reservation][:user_id] : current_user.id - price = transaction_amount(current_user.admin? || (current_user.manager? && current_user.id != user_id), user_id) + user_id = current_user.admin? || current_user.manager? ? params[:customer_id] : current_user.id + price = transaction_amount(user_id) authorize ReservationContext.new(Reservation, price[:amount], user_id) @@ -62,7 +62,7 @@ class API::ReservationsController < API::ApiController private - def transaction_amount(is_admin, user_id) + def transaction_amount(user_id) user = User.find(user_id) cs = CartService.new(current_user) cart = cs.from_hash(customer_id: user_id, @@ -71,7 +71,7 @@ class API::ReservationsController < API::ApiController }, reservation: reservation_params, coupon_code: coupon_params[:coupon_code], - payment_schedule: !schedule.nil?) + payment_schedule: reservation_params[:payment_schedule]) price_details = cart.total # Subtract wallet amount from total diff --git a/app/controllers/api/stripe_controller.rb b/app/controllers/api/stripe_controller.rb index b2f97a1be..e0769b57c 100644 --- a/app/controllers/api/stripe_controller.rb +++ b/app/controllers/api/stripe_controller.rb @@ -30,7 +30,7 @@ class API::StripeController < API::PaymentsController currency: Setting.get('stripe_currency'), confirmation_method: 'manual', confirm: true, - customer: current_user.stp_customer_id # FIXME + customer: current_user.payment_gateway_object.gateway_object_id }, { api_key: Setting.get('stripe_secret_key') } ) elsif params[:payment_intent_id].present? @@ -71,7 +71,7 @@ class API::StripeController < API::PaymentsController def setup_intent user = User.find(params[:user_id]) key = Setting.get('stripe_secret_key') - @intent = Stripe::SetupIntent.create({ customer: user.stp_customer_id }, { api_key: key }) + @intent = Stripe::SetupIntent.create({ customer: user.payment_gateway_object.gateway_object_id }, { api_key: key }) render json: { id: @intent.id, client_secret: @intent.client_secret } end @@ -96,7 +96,7 @@ class API::StripeController < API::PaymentsController def update_card user = User.find(params[:user_id]) key = Setting.get('stripe_secret_key') - Stripe::Customer.update(user.stp_customer_id, + Stripe::Customer.update(user.payment_gateway_object.gateway_object_id, { invoice_settings: { default_payment_method: params[:payment_method_id] } }, { api_key: key }) render json: { updated: true }, status: :ok diff --git a/app/controllers/api/subscriptions_controller.rb b/app/controllers/api/subscriptions_controller.rb index f8e3a3d95..3b0228939 100644 --- a/app/controllers/api/subscriptions_controller.rb +++ b/app/controllers/api/subscriptions_controller.rb @@ -57,7 +57,7 @@ class API::SubscriptionsController < API::ApiController plan_id: subscription_params[:plan_id] }, coupon_code: coupon_params[:coupon_code], - payment_schedule: !schedule.nil?) + payment_schedule: subscription_params[:payment_schedule]) price_details = cart.total user = User.find(user_id) diff --git a/app/doc/open_api/v1/invoices_doc.rb b/app/doc/open_api/v1/invoices_doc.rb index c365d114c..3a581cc08 100644 --- a/app/doc/open_api/v1/invoices_doc.rb +++ b/app/doc/open_api/v1/invoices_doc.rb @@ -16,7 +16,6 @@ class OpenAPI::V1::InvoicesDoc < OpenAPI::V1::BaseDoc description "Index of users' invoices, with optional pagination. Order by *created_at* descendant." param_group :pagination param :user_id, [Integer, Array], optional: true, desc: 'Scope the request to one or various users.' - # FIXME example <<-INVOICES # /open_api/v1/invoices?user_id=211&page=1&per_page=3 { diff --git a/app/frontend/src/javascript/components/payment/abstract-payment-modal.tsx b/app/frontend/src/javascript/components/payment/abstract-payment-modal.tsx index eb1b182cc..54ce16b0d 100644 --- a/app/frontend/src/javascript/components/payment/abstract-payment-modal.tsx +++ b/app/frontend/src/javascript/components/payment/abstract-payment-modal.tsx @@ -81,7 +81,7 @@ export const AbstractPaymentModal: React.FC = ({ isOp */ useEffect(() => { if (!cartItems) return; - WalletAPI.getByUser(cartItems.reservation?.user_id || cartItems.subscription?.user_id).then((wallet) => { + WalletAPI.getByUser(cartItems.customer_id).then((wallet) => { setWallet(wallet); PriceAPI.compute(cartItems).then((res) => { setPrice(res); diff --git a/app/frontend/src/javascript/controllers/events.js.erb b/app/frontend/src/javascript/controllers/events.js.erb index 562bd4163..a57821fbc 100644 --- a/app/frontend/src/javascript/controllers/events.js.erb +++ b/app/frontend/src/javascript/controllers/events.js.erb @@ -632,12 +632,11 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', ' * @return {{reservation:Object, coupon_code:string}} */ const mkRequestParams = function (reservation, coupon) { - const params = { + return { + customer_id: reservation.user_id, reservation, coupon_code: ((coupon ? coupon.code : undefined)) }; - - return params; }; /** diff --git a/app/frontend/src/javascript/directives/cart.js b/app/frontend/src/javascript/directives/cart.js index bab7e07e7..784432da4 100644 --- a/app/frontend/src/javascript/directives/cart.js +++ b/app/frontend/src/javascript/directives/cart.js @@ -680,18 +680,12 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs', /** * Create a hash map implementing the Subscription specs * @param planId {number} - * @param userId {number} - * @param schedule {boolean} - * @param method {String} 'stripe' | 'payzen' | '' - * @return {{subscription: {payment_schedule: boolean, user_id: number, plan_id: number}}} + * @return {{subscription: {plan_id: number}}} */ - const mkSubscription = function (planId, userId, schedule, method) { + const mkSubscription = function (planId) { return { subscription: { - plan_id: planId, - user_id: userId, - payment_schedule: schedule, - payment_method: method + plan_id: planId } }; }; @@ -703,11 +697,15 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs', * @return {CartItems} */ const mkCartItems = function (reservation, paymentMethod) { - let request = { reservation }; + const request = { + customer_id: reservation.user_id, + payment_schedule: $scope.schedule.requested_schedule, + payment_method: paymentMethod + }; if (reservation.slots_attributes.length === 0 && reservation.plan_id) { - request = mkSubscription($scope.selectedPlan.id, reservation.user_id, $scope.schedule.requested_schedule, paymentMethod); + Object.assign(request, mkSubscription($scope.selectedPlan.id)); } else { - request.reservation.payment_method = paymentMethod; + Object.assign(request, { reservation }); } return mkRequestParams(request, $scope.coupon.applied); }; diff --git a/app/frontend/src/javascript/directives/stripe-form.js b/app/frontend/src/javascript/directives/stripe-form.js deleted file mode 100644 index cd0929cff..000000000 --- a/app/frontend/src/javascript/directives/stripe-form.js +++ /dev/null @@ -1,102 +0,0 @@ -/* global Stripe */ - -/** - * This directive allows to extend a form with the Stripe payment input and error handling area. - * Strong-customer authentication is supported. - * -- - * https://stripe.com/docs/payments/payment-intents/web-manual - */ -Application.Directives.directive('stripeForm', ['Payment', 'growl', '_t', - function (Payment, growl, _t) { - return ({ - restrict: 'A', - scope: { - cartItems: '=', - onPaymentSuccess: '=', - stripeKey: '@' - }, - link: function ($scope, element, attributes) { - const stripe = Stripe($scope.stripeKey); - const elements = stripe.elements(); - - const style = { - base: { - color: '#32325d', - fontFamily: '"Helvetica Neue", Helvetica, sans-serif', - fontSmoothing: 'antialiased', - fontSize: '16px', - '::placeholder': { - color: '#aab7c4' - } - }, - invalid: { - color: '#fa755a', - iconColor: '#fa755a' - } - }; - - const card = elements.create('card', { style, hidePostalCode: true }); - - card.addEventListener('change', function ({ error }) { - const displayError = document.getElementById('card-errors'); - if (error) { - displayError.textContent = error.message; - } else { - displayError.textContent = ''; - } - }); - - // Add an instance of the card Element into the `card-element`
. - const form = angular.element(element); - const cardElement = form.find('#card-element'); - card.mount(cardElement[0]); - - form.bind('submit', function () { - const button = form.find('button'); - button.prop('disabled', true); - - stripe.createPaymentMethod('card', card).then(function ({ paymentMethod, error }) { - if (error) { - growl.error(error.message); - button.prop('disabled', false); - } else { - // Send paymentMethod.id to your server (see Step 2) - 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 handleServerResponse (response, confirmButton) { - if (response.error) { - if (response.error.statusText) { - growl.error(response.error.statusText); - } else { - growl.error(`${_t('app.shared.messages.payment_card_error')} ${response.error}`); - } - confirmButton.prop('disabled', false); - } else if (response.requires_action) { - // Use Stripe.js to handle required card action - stripe.handleCardAction( - response.payment_intent_client_secret - ).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) { - handleServerResponse(confirmResult, confirmButton); - }, function (error) { handleServerResponse({ error }, confirmButton); }); - } - }); - } else { - $scope.onPaymentSuccess(response); - } - } - } - }); - }]); diff --git a/app/models/cart_item/base_item.rb b/app/models/cart_item/base_item.rb index 38141fd29..b89479a48 100644 --- a/app/models/cart_item/base_item.rb +++ b/app/models/cart_item/base_item.rb @@ -5,8 +5,6 @@ module CartItem; end # This is an abstract class implemented by classes that can be added to the shopping cart class CartItem::BaseItem - self.abstract_class = true - def price { elements: {}, amount: 0 } end diff --git a/app/models/cart_item/event_reservation.rb b/app/models/cart_item/event_reservation.rb index 28e757123..02e6f675b 100644 --- a/app/models/cart_item/event_reservation.rb +++ b/app/models/cart_item/event_reservation.rb @@ -9,7 +9,7 @@ class CartItem::EventReservation < CartItem::Reservation super(customer, operator, event, slots) @normal_tickets = normal_tickets - @other_tickets = other_tickets + @other_tickets = other_tickets || [] end def price diff --git a/app/models/cart_item/reservation.rb b/app/models/cart_item/reservation.rb index 4f61eb7b8..7e29339b4 100644 --- a/app/models/cart_item/reservation.rb +++ b/app/models/cart_item/reservation.rb @@ -75,6 +75,8 @@ class CartItem::Reservation < CartItem::BaseItem # Compute the number of remaining hours in the users current credits (for machine or space) ## def credits_hours(credits, new_plan_being_bought = false) + return 0 unless credits + hours_available = credits.hours unless new_plan_being_bought user_credit = @customer.users_credits.find_by(credit_id: credits.id) diff --git a/app/models/cart_item/training_reservation.rb b/app/models/cart_item/training_reservation.rb index b892f8f4c..c8f629608 100644 --- a/app/models/cart_item/training_reservation.rb +++ b/app/models/cart_item/training_reservation.rb @@ -13,7 +13,7 @@ class CartItem::TrainingReservation < CartItem::Reservation end def price - base_amount = @reservable.amount_by_group(@customer.group_id, plan_id: @plan.try(:id)).amount + base_amount = @reservable.amount_by_group(@customer.group_id).amount is_privileged = @operator.admin? || (@operator.manager? && @operator.id != @customer.id) elements = { slots: [] } @@ -25,7 +25,7 @@ class CartItem::TrainingReservation < CartItem::Reservation slot, is_privileged, elements: elements, - has_credits: (@user.training_credits.size < hours_available), + has_credits: (@customer.training_credits.size < hours_available), is_division: false) end diff --git a/app/models/machine.rb b/app/models/machine.rb index 0d89947e9..e69b56ed5 100644 --- a/app/models/machine.rb +++ b/app/models/machine.rb @@ -26,6 +26,8 @@ class Machine < ApplicationRecord has_many :credits, as: :creditable, dependent: :destroy has_many :plans, through: :credits + has_one :payment_gateway_object, as: :item + after_create :create_statistic_subtype after_create :create_machine_prices diff --git a/app/models/payment_gateway_object.rb b/app/models/payment_gateway_object.rb index 65005df06..9651e5832 100644 --- a/app/models/payment_gateway_object.rb +++ b/app/models/payment_gateway_object.rb @@ -10,6 +10,11 @@ class PaymentGatewayObject < ApplicationRecord belongs_to :subscription, foreign_type: 'Subscription', foreign_key: 'item_id' belongs_to :payment_schedule, foreign_type: 'PaymentSchedule', foreign_key: 'item_id' belongs_to :payment_schedule_item, foreign_type: 'PaymentScheduleItem', foreign_key: 'item_id' + belongs_to :user, foreign_type: 'User', foreign_key: 'item_id' + belongs_to :plan, foreign_type: 'Plan', foreign_key: 'item_id' + belongs_to :machine, foreign_type: 'Machine', foreign_key: 'item_id' + belongs_to :space, foreign_type: 'Space', foreign_key: 'item_id' + belongs_to :training, foreign_type: 'Training', foreign_key: 'item_id' def gateway_object Payment::ItemBuilder.build(gateway_object_type, gateway_object_id) diff --git a/app/models/payment_schedule.rb b/app/models/payment_schedule.rb index be956b4a6..c6a2c1b97 100644 --- a/app/models/payment_schedule.rb +++ b/app/models/payment_schedule.rb @@ -52,6 +52,10 @@ class PaymentSchedule < PaymentDocument payment_gateway_objects.map(&:gateway_object).find(&:payment_mean?) end + def gateway_subscription + payment_gateway_objects.map(&:gateway_object).find { |item| !item.payment_mean? } + end + def user invoicing_profile.user end diff --git a/app/models/payment_schedule_item.rb b/app/models/payment_schedule_item.rb index 4683091dd..6f18c9b95 100644 --- a/app/models/payment_schedule_item.rb +++ b/app/models/payment_schedule_item.rb @@ -14,10 +14,9 @@ class PaymentScheduleItem < Footprintable def payment_intent return unless payment_gateway_object - # FIXME - key = Setting.get('stripe_secret_key') - stp_invoice = Stripe::Invoice.retrieve(stp_invoice_id, api_key: key) - Stripe::PaymentIntent.retrieve(stp_invoice.payment_intent, api_key: key) + + stp_invoice = payment_gateway_object.gateway_object.retrieve + Stripe::PaymentIntent.retrieve(stp_invoice.payment_intent, api_key: Setting.get('stripe_secret_key')) end def self.columns_out_of_footprint diff --git a/app/models/plan.rb b/app/models/plan.rb index 4455b3734..0b7a9bf64 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -12,6 +12,7 @@ class Plan < ApplicationRecord has_many :subscriptions has_one :plan_file, as: :viewable, dependent: :destroy has_many :prices, dependent: :destroy + has_one :payment_gateway_object, as: :item extend FriendlyId friendly_id :base_name, use: :slugged diff --git a/app/models/shopping_cart.rb b/app/models/shopping_cart.rb index f80edccd2..2f7f26a64 100644 --- a/app/models/shopping_cart.rb +++ b/app/models/shopping_cart.rb @@ -25,7 +25,7 @@ class ShoppingCart @items.map(&:price).each do |price| total_amount += price[:amount] - all_elements.merge(price[:elements]) do |_key, old_val, new_val| + all_elements = all_elements.merge(price[:elements]) do |_key, old_val, new_val| old_val | new_val end end diff --git a/app/models/space.rb b/app/models/space.rb index 95bb04f5a..17ca2434e 100644 --- a/app/models/space.rb +++ b/app/models/space.rb @@ -24,6 +24,8 @@ class Space < ApplicationRecord has_many :prices, as: :priceable, dependent: :destroy has_many :credits, as: :creditable, dependent: :destroy + has_one :payment_gateway_object, as: :item + after_create :create_statistic_subtype after_create :create_space_prices after_create :update_stripe_product diff --git a/app/models/training.rb b/app/models/training.rb index 7010ff68e..df790af2f 100644 --- a/app/models/training.rb +++ b/app/models/training.rb @@ -26,6 +26,8 @@ class Training < ApplicationRecord has_many :credits, as: :creditable, dependent: :destroy has_many :plans, through: :credits + has_one :payment_gateway_object, as: :item + after_create :create_statistic_subtype after_create :create_trainings_pricings after_create :update_stripe_product diff --git a/app/models/user.rb b/app/models/user.rb index 4fda4b147..e508b287f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -45,6 +45,8 @@ class User < ApplicationRecord has_many :exports, dependent: :destroy has_many :imports, dependent: :nullify + has_one :payment_gateway_object, as: :item + # fix for create admin user before_save do email&.downcase! @@ -177,11 +179,6 @@ class User < ApplicationRecord subscription.generate_and_save_invoice(operator_profile_id) end - def stripe_customer - # FIXME - Stripe::Customer.retrieve(stp_customer_id, api_key: Setting.get('stripe_secret_key')) - end - def active_for_authentication? super && is_active? end @@ -315,7 +312,7 @@ class User < ApplicationRecord blacklist = %w[id encrypted_password reset_password_token reset_password_sent_at remember_created_at sign_in_count current_sign_in_at last_sign_in_at current_sign_in_ip last_sign_in_ip confirmation_token confirmed_at confirmation_sent_at unconfirmed_email failed_attempts unlock_token locked_at created_at - updated_at stp_customer_id slug provider auth_token merged_at] + updated_at slug provider auth_token merged_at] User.columns_hash .map { |k, v| [k, v.type.to_s] } .delete_if { |col| blacklist.include?(col[0]) } diff --git a/app/services/cart_service.rb b/app/services/cart_service.rb index 6ec7ce20b..a3ff35952 100644 --- a/app/services/cart_service.rb +++ b/app/services/cart_service.rb @@ -11,12 +11,11 @@ class CartService # @see app/frontend/src/javascript/models/payment.ts > interface CartItems ## def from_hash(cart_items) - items = [] + @customer = customer(cart_items) plan_info = plan(cart_items) - @customer = User.find(cart_items[:customer_id]) - - items.push(CartItem::Subscription.new(plan_info[:plan])) if cart_items[:subscription] + items = [] + items.push(CartItem::Subscription.new(plan_info[:plan])) if plan_info[:new_subscription] items.push(reservable_from_hash(cart_items[:reservation], plan_info)) if cart_items[:reservation] coupon = CartItem::Coupon.new(@customer, @operator, cart_items[:coupon_code]) @@ -37,7 +36,7 @@ class CartService plan = if @customer.subscribed_plan new_plan_being_bought = false @customer.subscribed_plan - elsif cart_items[:subscription] + elsif cart_items[:subscription] && cart_items[:subscription][:plan_id] new_plan_being_bought = true Plan.find(cart_items[:subscription][:plan_id]) else @@ -47,6 +46,14 @@ class CartService { plan: plan, new_subscription: new_plan_being_bought } end + def customer(cart_items) + if @operator.admin? || (@operator.manager? && @operator.id != cart_items[:customer_id]) + User.find(cart_items[:customer_id]) + else + @operator + end + end + def reservable_from_hash(cart_item, plan_info) return nil if cart_item[:reservable_id].blank? diff --git a/app/services/invoices_service.rb b/app/services/invoices_service.rb index 77c95219a..6ba057235 100644 --- a/app/services/invoices_service.rb +++ b/app/services/invoices_service.rb @@ -78,12 +78,7 @@ class InvoicesService operator&.admin? || (operator&.manager? && operator != user) ? nil : Setting.get('payment_gateway') end - pgo = unless payment_id.nil? - { - gateway_object_id: payment_id, - gateway_object_type: payment_type - } - end + pgo = payment_id.nil? ? {} : { gateway_object_id: payment_id, gateway_object_type: payment_type } invoice = Invoice.new( invoiced: subscription || reservation, invoicing_profile: user.invoicing_profile, diff --git a/app/services/payment_schedule_service.rb b/app/services/payment_schedule_service.rb index 1d6fe81fe..13fd5ae1c 100644 --- a/app/services/payment_schedule_service.rb +++ b/app/services/payment_schedule_service.rb @@ -61,10 +61,12 @@ class PaymentScheduleService ps.scheduled = reservation || subscription ps.payment_method = payment_method if !payment_id.nil? && !payment_type.nil? - ps.payment_gateway_object = { + pgo = PaymentGatewayObject.new( gateway_object_id: payment_id, - gateway_object_type: payment_type - } + gateway_object_type: payment_type, + item: ps + ) + ps.payment_gateway_objects.push(pgo) end ps.operator_profile = operator.invoicing_profile ps.invoicing_profile = user.invoicing_profile diff --git a/app/services/stripe_service.rb b/app/services/stripe_service.rb index fdf10443d..d98be6d51 100644 --- a/app/services/stripe_service.rb +++ b/app/services/stripe_service.rb @@ -12,7 +12,7 @@ class StripeService case payment_schedule.scheduled_type when Reservation.name subscription = payment_schedule.scheduled.subscription - reservable_stp_id = payment_schedule.scheduled.reservable&.stp_product_id + reservable_stp_id = payment_schedule.scheduled.reservable&.payment_gateway_object&.gateway_object_id when Subscription.name subscription = payment_schedule.scheduled reservable_stp_id = nil @@ -26,13 +26,13 @@ class StripeService intent = Stripe::SetupIntent.retrieve(setup_intent_id, api_key: stripe_key) # subscription (recurring price) price = create_price(first_item.details['recurring'], - subscription.plan.stp_product_id, + subscription.plan.payment_gateway_object.gateway_object_id, nil, monthly: true) # other items (not recurring) items = subscription_invoice_items(payment_schedule, subscription, first_item, reservable_stp_id) stp_subscription = Stripe::Subscription.create({ - customer: payment_schedule.invoicing_profile.user.stp_customer_id, + customer: payment_schedule.invoicing_profile.user.payment_gateway_object.gateway_object_id, cancel_at: (payment_schedule.ordered_items.last.due_date + 3.day).to_i, add_invoice_items: items, coupon: payment_schedule.coupon&.code, @@ -41,7 +41,9 @@ class StripeService ], default_payment_method: intent[:payment_method] }, { api_key: stripe_key }) - payment_schedule.update_attributes(stp_subscription_id: stp_subscription.id) + pgo = PaymentGatewayObject.new(item: payment_schedule) + pgo.gateway_object = stp_subscription + pgo.save! end def create_stripe_coupon(coupon_id) @@ -72,7 +74,7 @@ class StripeService # adjustment: when dividing the price of the plan / months, sometimes it forces us to round the amount per month. # The difference is invoiced here p1 = create_price(first_item.details['adjustment'], - subscription.plan.stp_product_id, + subscription.plan.payment_gateway_object.gateway_object_id, "Price adjustment for payment schedule #{payment_schedule.id}") items.push(price: p1[:id]) end @@ -104,7 +106,7 @@ class StripeService def handle_wallet_transaction(payment_schedule) return unless payment_schedule.wallet_amount - customer_id = payment_schedule.invoicing_profile.user.stp_customer_id + customer_id = payment_schedule.invoicing_profile.user.payment_gateway_object.gateway_object_id Stripe::Customer.update(customer_id, { balance: -payment_schedule.wallet_amount }, { api_key: Setting.get('stripe_secret_key') }) end end diff --git a/app/services/subscriptions/subscribe.rb b/app/services/subscriptions/subscribe.rb index 316e3f27a..508c83515 100644 --- a/app/services/subscriptions/subscribe.rb +++ b/app/services/subscriptions/subscribe.rb @@ -62,8 +62,9 @@ class Subscriptions::Subscribe if new_sub.save schedule = subscription.original_payment_schedule - cs = CartService.new(current_user) - cart = cs.from_hash(customer_id: @user_id, + operator = InvoicingProfile.find(@operator_profile_id).user + cs = CartService.new(operator) + cart = cs.from_hash(customer_id: subscription.user.id, subscription: { plan_id: subscription.plan_id }, @@ -84,7 +85,7 @@ class Subscriptions::Subscribe details) end payment.save - payment.post_save(schedule&.stp_setup_intent_id) + payment.post_save(schedule&.gateway_payment_mean&.id) UsersCredits::Manager.new(user: new_sub.user).reset_credits return new_sub end diff --git a/app/workers/payment_schedule_item_worker.rb b/app/workers/payment_schedule_item_worker.rb index bbbb07538..f5eac38b0 100644 --- a/app/workers/payment_schedule_item_worker.rb +++ b/app/workers/payment_schedule_item_worker.rb @@ -21,7 +21,7 @@ class PaymentScheduleItemWorker if psi.payment_schedule.payment_method == 'card' ### Stripe stripe_key = Setting.get('stripe_secret_key') - stp_subscription = Stripe::Subscription.retrieve(psi.payment_schedule.stp_subscription_id, api_key: stripe_key) + stp_subscription = psi.payment_schedule.gateway_subscription.retrieve stp_invoice = Stripe::Invoice.retrieve(stp_subscription.latest_invoice, api_key: stripe_key) if stp_invoice.status == 'paid' ##### Stripe / Successfully paid diff --git a/app/workers/stripe_worker.rb b/app/workers/stripe_worker.rb index 9ace8ad90..ab4d4de65 100644 --- a/app/workers/stripe_worker.rb +++ b/app/workers/stripe_worker.rb @@ -33,9 +33,9 @@ class StripeWorker def create_or_update_stp_product(class_name, id) object = class_name.constantize.find(id) - if !object.stp_product_id.nil? + if !object.payment_gateway_object.nil? Stripe::Product.update( - object.stp_product_id, + object.payment_gateway_object.gateway_object_id, { name: object.name }, { api_key: Setting.get('stripe_secret_key') } ) @@ -49,12 +49,15 @@ class StripeWorker } }, { api_key: Setting.get('stripe_secret_key') } ) - object.update_attributes(stp_product_id: product.id) + pgo = PaymentGatewayObject.new(item: object) + pgo.gateway_object = product + pgo.save! puts "Stripe product was created for the #{class_name} \##{id}" end rescue Stripe::InvalidRequestError - STDERR.puts "WARNING: saved stp_product_id (#{object.stp_product_id}) does not match on Stripe, recreating..." + obj_id = object.payment_gateway_object.gateway_object_id + STDERR.puts "WARNING: saved payment_gateway_object#id (#{obj_id}) does not match on Stripe, recreating..." product = Stripe::Product.create( { name: object.name, @@ -64,7 +67,9 @@ class StripeWorker } }, { api_key: Setting.get('stripe_secret_key') } ) - object.update_attributes(stp_product_id: product.id) + pgo = PaymentGatewayObject.new(item: object) + pgo.gateway_object = product + pgo.save! puts "Stripe product was created for the #{class_name} \##{id}" end end diff --git a/app/workers/sync_members_on_stripe_worker.rb b/app/workers/sync_members_on_stripe_worker.rb index 27a387a24..387981229 100644 --- a/app/workers/sync_members_on_stripe_worker.rb +++ b/app/workers/sync_members_on_stripe_worker.rb @@ -11,7 +11,7 @@ class SyncMembersOnStripeWorker User.online_payers.each_with_index do |member, index| logger.debug "#{index} / #{total}" begin - stp_customer = Stripe::Customer.retrieve(member.stp_customer_id, api_key: Setting.get('stripe_secret_key')) + stp_customer = member.payment_gateway_objects.gateway_object.retrieve StripeWorker.new.create_stripe_customer(member.id) if stp_customer.nil? || stp_customer[:deleted] rescue Stripe::InvalidRequestError StripeWorker.new.create_stripe_customer(member.id) diff --git a/db/structure.sql b/db/structure.sql index f046c7136..9dc35298e 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -108,8 +108,8 @@ SET default_tablespace = ''; CREATE TABLE public.abuses ( id integer NOT NULL, - signaled_id integer, signaled_type character varying, + signaled_id integer, first_name character varying, last_name character varying, email character varying, @@ -187,8 +187,8 @@ CREATE TABLE public.addresses ( locality character varying, country character varying, postal_code character varying, - placeable_id integer, placeable_type character varying, + placeable_id integer, created_at timestamp without time zone, updated_at timestamp without time zone ); @@ -263,8 +263,8 @@ CREATE TABLE public.ar_internal_metadata ( CREATE TABLE public.assets ( id integer NOT NULL, - viewable_id integer, viewable_type character varying, + viewable_id integer, attachment character varying, type character varying, created_at timestamp without time zone, @@ -504,8 +504,8 @@ ALTER SEQUENCE public.coupons_id_seq OWNED BY public.coupons.id; CREATE TABLE public.credits ( id integer NOT NULL, - creditable_id integer, creditable_type character varying, + creditable_id integer, plan_id integer, hours integer, created_at timestamp without time zone, @@ -1045,8 +1045,8 @@ ALTER SEQUENCE public.invoice_items_id_seq OWNED BY public.invoice_items.id; CREATE TABLE public.invoices ( id integer NOT NULL, - invoiced_id integer, invoiced_type character varying, + invoiced_id integer, total integer, created_at timestamp without time zone, updated_at timestamp without time zone, @@ -1223,15 +1223,15 @@ ALTER SEQUENCE public.machines_id_seq OWNED BY public.machines.id; CREATE TABLE public.notifications ( id integer NOT NULL, receiver_id integer, - attached_object_id integer, attached_object_type character varying, + attached_object_id integer, notification_type_id integer, is_read boolean DEFAULT false, created_at timestamp without time zone, updated_at timestamp without time zone, receiver_type character varying, is_send boolean DEFAULT false, - meta_data jsonb DEFAULT '{}'::jsonb + meta_data jsonb DEFAULT '"{}"'::jsonb ); @@ -1687,8 +1687,8 @@ CREATE TABLE public.prices ( id integer NOT NULL, group_id integer, plan_id integer, - priceable_id integer, priceable_type character varying, + priceable_id integer, amount integer, created_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL @@ -2003,8 +2003,8 @@ CREATE TABLE public.reservations ( message text, created_at timestamp without time zone, updated_at timestamp without time zone, - reservable_id integer, reservable_type character varying, + reservable_id integer, nb_reserve_places integer, statistic_profile_id integer ); @@ -2036,8 +2036,8 @@ ALTER SEQUENCE public.reservations_id_seq OWNED BY public.reservations.id; CREATE TABLE public.roles ( id integer NOT NULL, name character varying, - resource_id integer, resource_type character varying, + resource_id integer, created_at timestamp without time zone, updated_at timestamp without time zone ); @@ -2969,8 +2969,8 @@ CREATE TABLE public.users_roles ( CREATE TABLE public.wallet_transactions ( id integer NOT NULL, wallet_id integer, - transactable_id integer, transactable_type character varying, + transactable_id integer, transaction_type character varying, amount integer, created_at timestamp without time zone NOT NULL, @@ -4074,6 +4074,14 @@ ALTER TABLE ONLY public.roles ADD CONSTRAINT roles_pkey PRIMARY KEY (id); +-- +-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.schema_migrations + ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); + + -- -- Name: settings settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -5152,29 +5160,6 @@ CREATE INDEX profiles_lower_unaccent_last_name_trgm_idx ON public.profiles USING CREATE INDEX projects_search_vector_idx ON public.projects USING gin (search_vector); --- --- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX unique_schema_migrations ON public.schema_migrations USING btree (version); - - --- --- Name: accounting_periods accounting_periods_del_protect; Type: RULE; Schema: public; Owner: - --- - -CREATE RULE accounting_periods_del_protect AS - ON DELETE TO public.accounting_periods DO INSTEAD NOTHING; - - --- --- Name: accounting_periods accounting_periods_upd_protect; Type: RULE; Schema: public; Owner: - --- - -CREATE RULE accounting_periods_upd_protect AS - ON UPDATE TO public.accounting_periods DO INSTEAD NOTHING; - - -- -- Name: projects projects_search_content_trigger; Type: TRIGGER; Schema: public; Owner: - -- @@ -5717,7 +5702,6 @@ INSERT INTO "schema_migrations" (version) VALUES ('20140605125131'), ('20140605142133'), ('20140605151442'), -('20140606133116'), ('20140609092700'), ('20140609092827'), ('20140610153123'), @@ -5786,14 +5770,12 @@ INSERT INTO "schema_migrations" (version) VALUES ('20150507075620'), ('20150512123546'), ('20150520132030'), -('20150520133409'), ('20150526130729'), ('20150527153312'), ('20150529113555'), ('20150601125944'), ('20150603104502'), ('20150603104658'), -('20150603133050'), ('20150604081757'), ('20150604131525'), ('20150608142234'), @@ -5875,7 +5857,6 @@ INSERT INTO "schema_migrations" (version) VALUES ('20160905142700'), ('20160906094739'), ('20160906094847'), -('20160906145713'), ('20160915105234'), ('20161123104604'), ('20170109085345'), diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index 724f38fa4..6af1f8f90 100755 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -18,4 +18,5 @@ fi RAILS_ENV='test' bin/rails db:drop RAILS_ENV='test' bin/rails db:create RAILS_ENV='test' bin/rails db:migrate +clear STRIPE_PUBLISHABLE_KEY="$stripe_public_key" STRIPE_API_KEY="$stripe_secret_key" RAILS_ENV='test' bundle exec bin/rails test "$@" diff --git a/test/fixtures/invoices.yml b/test/fixtures/invoices.yml index 513e48eb2..98c930eff 100644 --- a/test/fixtures/invoices.yml +++ b/test/fixtures/invoices.yml @@ -3,7 +3,6 @@ invoice_1: id: 1 invoiced_id: 1 invoiced_type: Subscription - stp_invoice_id: in_17wpf92sOmf47Nz9itj6vmJw total: 10000 created_at: 2012-03-12 11:03:31.651441000 Z updated_at: 2012-03-12 11:03:31.651441000 Z @@ -24,7 +23,6 @@ invoice_2: id: 2 invoiced_id: 2 invoiced_type: Subscription - stp_invoice_id: total: 2000 created_at: 2012-03-12 13:40:22.342717000 Z updated_at: 2012-03-12 13:40:22.342717000 Z @@ -45,7 +43,6 @@ invoice_3: id: 3 invoiced_id: 3 invoiced_type: Subscription - stp_invoice_id: total: 3000 created_at: 2015-06-10 11:20:01.341130000 Z updated_at: 2015-06-10 11:20:01.341130000 Z @@ -67,7 +64,6 @@ invoice_4: id: 4 invoiced_id: 1 invoiced_type: Reservation - stp_invoice_id: total: 0 created_at: 2016-04-05 08:35:52.931187000 Z updated_at: 2016-04-05 08:35:52.931187000 Z @@ -88,7 +84,6 @@ invoice_5: id: 5 invoiced_id: 2 invoiced_type: Reservation - stp_invoice_id: total: 1500 created_at: 2016-04-05 08:36:46.853368000 Z updated_at: 2016-04-05 08:36:46.853368000 Z @@ -109,7 +104,6 @@ invoice_6: id: 6 invoiced_id: 4 invoiced_type: Subscription - stp_invoice_id: total: 3000 created_at: 2021-01-04 14:51:21.616153182 Z updated_at: 2021-01-04 14:51:21.616153182 Z diff --git a/test/fixtures/machines.yml b/test/fixtures/machines.yml index 38a026d4e..527ea6ca2 100644 --- a/test/fixtures/machines.yml +++ b/test/fixtures/machines.yml @@ -22,7 +22,6 @@ machine_1: created_at: 2016-04-04 14:11:34.210242000 Z updated_at: 2016-04-04 14:11:34.210242000 Z slug: decoupeuse-laser - stp_product_id: prod_IZPyHpMCl38iQl machine_2: id: 2 @@ -39,7 +38,6 @@ machine_2: created_at: 2016-04-04 14:11:34.274025000 Z updated_at: 2016-04-04 14:11:34.274025000 Z slug: decoupeuse-vinyle - stp_product_id: prod_IZPyPShaaRgSML machine_3: id: 3 @@ -56,7 +54,6 @@ machine_3: created_at: 2016-04-04 14:11:34.304247000 Z updated_at: 2016-04-04 14:11:34.304247000 Z slug: shopbot-grande-fraiseuse - stp_product_id: prod_IZPyEjmdfMowhY machine_4: id: 4 @@ -70,7 +67,6 @@ machine_4: created_at: 2001-01-01 14:11:34.341810000 Z updated_at: 2001-01-01 14:11:34.341810000 Z slug: imprimante-3d - stp_product_id: prod_IZPy85vZOQpAo5 machine_5: id: 5 @@ -93,7 +89,6 @@ machine_5: created_at: 2016-04-04 14:11:34.379481000 Z updated_at: 2016-04-04 14:11:34.379481000 Z slug: petite-fraiseuse - stp_product_id: prod_IZPyBJEgbcpWMC machine_6: id: 6 @@ -128,4 +123,3 @@ machine_6: created_at: 2016-04-04 14:11:34.424740000 Z updated_at: 2016-04-04 14:11:34.424740000 Z slug: form1-imprimante-3d - stp_product_id: prod_IZPyjCzvLmLWAz diff --git a/test/fixtures/payment_gateway_objects.yml b/test/fixtures/payment_gateway_objects.yml index 810867bcb..d15d2624b 100644 --- a/test/fixtures/payment_gateway_objects.yml +++ b/test/fixtures/payment_gateway_objects.yml @@ -6,6 +6,156 @@ pgo_1: pgo2: item_type: 'Subscription' - item_id: 1 - gateway_object_type: 'Stripe::Subscription' - gateway_object_id: 'sub_8DGB4ErIc2asOv' + item_id: 1 + gateway_object_type: 'Stripe::Subscription' + gateway_object_id: 'sub_8DGB4ErIc2asOv' + +pgo3: + item_type: 'Invoice' + item_id: 1 + gateway_object_type: 'Stripe::Invoice' + gateway_object_id: 'in_17wpf92sOmf47Nz9itj6vmJw' + +pgo4: + item_type: 'Plan' + item_id: 1 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyXhfyNiGkWR' + +pgo5: + item_type: 'Plan' + item_id: 2 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPykam7a4satn' + +pgo6: + item_type: 'Plan' + item_id: 3 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyM4N36h86G0' + +pgo7: + item_type: 'Plan' + item_id: 4 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZQAhb9nLu4jfN' + +pgo8: + item_type: 'Machine' + item_id: 1 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyHpMCl38iQl' + +pgo9: + item_type: 'Machine' + item_id: 2 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyPShaaRgSML' + +pgo10: + item_type: 'Machine' + item_id: 3 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyEjmdfMowhY' + +pgo11: + item_type: 'Machine' + item_id: 4 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPy85vZOQpAo5' + +pgo12: + item_type: 'Machine' + item_id: 5 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyBJEgbcpWMC' + +pgo13: + item_type: 'Machine' + item_id: 6 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyjCzvLmLWAz' + +pgo14: + item_type: 'Space' + item_id: 1 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyHjIb2owoB8' + +pgo15: + item_type: 'Training' + item_id: 1 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyXw6BDBBFOg' + +pgo16: + item_type: 'Training' + item_id: 2 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPytTl1wSB5jH' + +pgo17: + item_type: 'Training' + item_id: 3 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyAA1A4QfEyL' + +pgo18: + item_type: 'Training' + item_id: 4 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyU27NjDSmqB' + +pgo19: + item_type: 'Training' + item_id: 5 + gateway_object_type: 'Stripe::Product' + gateway_object_id: 'prod_IZPyvdgQHMByB3' + +pgo20: + item_type: 'User' + item_id: 1 + gateway_object_type: 'Stripe::Customer' + gateway_object_id: 'cus_8CyNk3UTi8lvCc' + +pgo21: + item_type: 'User' + item_id: 2 + gateway_object_type: 'Stripe::Customer' + gateway_object_id: 'cus_8Di1wjdVktv5kt' + +pgo22: + item_type: 'User' + item_id: 3 + gateway_object_type: 'Stripe::Customer' + gateway_object_id: 'cus_8CzHcwBJtlA3IL' + +pgo23: + item_type: 'User' + item_id: 4 + gateway_object_type: 'Stripe::Customer' + gateway_object_id: 'cus_8CzKe50I0J1gaI' + +pgo24: + item_type: 'User' + item_id: 5 + gateway_object_type: 'Stripe::Customer' + gateway_object_id: 'cus_8CzNtM08NVlSGN' + +pgo25: + item_type: 'User' + item_id: 6 + gateway_object_type: 'Stripe::Customer' + gateway_object_id: 'cus_8CzQK5uXPeyh4K' + +pgo26: + item_type: 'User' + item_id: 7 + gateway_object_type: 'Stripe::Customer' + gateway_object_id: 'cus_8E2ys9zDZgetWX' + +pgo27: + item_type: 'User' + item_id: 8 + gateway_object_type: 'Stripe::Customer' + gateway_object_id: 'cus_IhIynmoJbzLpwX' diff --git a/test/fixtures/plans.yml b/test/fixtures/plans.yml index 834e07b46..e6de5e3cb 100644 --- a/test/fixtures/plans.yml +++ b/test/fixtures/plans.yml @@ -16,7 +16,6 @@ plan_1: ui_weight: 1 interval_count: 1 slug: mensuel - stp_product_id: prod_IZPyXhfyNiGkWR plan_2: id: 2 @@ -35,7 +34,6 @@ plan_2: ui_weight: 5 interval_count: 2 slug: sleede - stp_product_id: prod_IZPykam7a4satn plan_3: id: 3 @@ -55,7 +53,6 @@ plan_3: ui_weight: 0 interval_count: 1* slug: mensuel-tarif-reduit - stp_product_id: prod_IZPyM4N36h86G0 plan_schedulable: id: 4 @@ -75,4 +72,3 @@ plan_schedulable: interval_count: 1 monthly_payment: true slug: abonnement-mensualisable - stp_product_id: prod_IZQAhb9nLu4jfN diff --git a/test/fixtures/spaces.yml b/test/fixtures/spaces.yml index 8a50e82cc..242041286 100644 --- a/test/fixtures/spaces.yml +++ b/test/fixtures/spaces.yml @@ -7,4 +7,3 @@ space_1: created_at: 2017-02-15 15:55:04.123928000 Z updated_at: 2017-02-15 15:55:04.123928000 Z characteristics: Scie à chantourner, rabot, dégauchisseuse, chanfreineuse et pyrograveur - stp_product_id: prod_IZPyHjIb2owoB8 diff --git a/test/fixtures/trainings.yml b/test/fixtures/trainings.yml index 24d9521bd..a25c18e82 100644 --- a/test/fixtures/trainings.yml +++ b/test/fixtures/trainings.yml @@ -7,7 +7,6 @@ training_1: nb_total_places: slug: formation-imprimante-3d description: - stp_product_id: prod_IZPyXw6BDBBFOg training_2: id: 2 @@ -17,7 +16,6 @@ training_2: nb_total_places: slug: formation-laser-vinyle description: - stp_product_id: prod_IZPytTl1wSB5jH training_3: id: 3 @@ -27,7 +25,6 @@ training_3: nb_total_places: slug: formation-petite-fraiseuse-numerique description: - stp_product_id: prod_IZPyAA1A4QfEyL training_4: id: 4 @@ -37,7 +34,6 @@ training_4: nb_total_places: slug: formation-shopbot-grande-fraiseuse description: - stp_product_id: prod_IZPyU27NjDSmqB training_5: id: 5 @@ -47,4 +43,3 @@ training_5: nb_total_places: slug: formation-logiciel-2d description: - stp_product_id: prod_IZPyvdgQHMByB3 diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index fd1f41691..7d80696f7 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -1,3 +1,34 @@ +user_1: + id: 1 + username: admin + email: admin@fab-manager.com + encrypted_password: "$2a$10$LtQ2OggropcXpmcsPTEPruuGZrwuFYGOo8qjh.po91YDna/K4/Bbe" + reset_password_token: + reset_password_sent_at: + remember_created_at: + sign_in_count: 8 + current_sign_in_at: 2016-04-05 08:36:08.361260000 Z + last_sign_in_at: 2016-04-05 08:34:28.227054000 Z + current_sign_in_ip: 127.0.0.1 + last_sign_in_ip: 127.0.0.1 + confirmation_token: + confirmed_at: 2016-04-05 08:40:21.514533000 Z + confirmation_sent_at: 2001-01-01 14:11:33.852719000 Z + unconfirmed_email: + failed_attempts: 0 + unlock_token: + locked_at: + created_at: 2001-01-01 14:11:33.852719000 Z + updated_at: 2016-04-05 08:36:08.362215000 Z + is_allow_contact: true + group_id: 3 + slug: admin + is_active: true + provider: + uid: + auth_token: + merged_at: + is_allow_newsletter: true user_2: id: 2 @@ -23,7 +54,6 @@ user_2: updated_at: 2016-04-04 15:00:43.556308000 Z is_allow_contact: true group_id: 1 - stp_customer_id: cus_8Di1wjdVktv5kt slug: jdupond is_active: true provider: @@ -32,105 +62,6 @@ user_2: merged_at: is_allow_newsletter: true -user_4: - id: 4 - username: kdumas - email: kevin.dumas@orange.fr - encrypted_password: "$2a$10$N6Q4SHkkUtwlnMNFvN6nF.rkmLFTIPsARk7xEuR1Dws7Dy2sSrSOW" - reset_password_token: - reset_password_sent_at: - remember_created_at: - sign_in_count: 0 - current_sign_in_at: - last_sign_in_at: - current_sign_in_ip: - last_sign_in_ip: - confirmation_token: - confirmed_at: 2016-04-04 15:11:02.968494000 Z - confirmation_sent_at: 2016-04-04 15:10:42.376191000 Z - unconfirmed_email: - failed_attempts: 0 - unlock_token: - locked_at: - created_at: 2016-04-04 15:10:42.340868000 Z - updated_at: 2016-04-04 15:11:02.969182000 Z - is_allow_contact: true - group_id: 2 - stp_customer_id: cus_8CzKe50I0J1gaI - slug: kdumas - is_active: true - provider: - uid: - auth_token: - merged_at: - is_allow_newsletter: false - -user_6: - id: 6 - username: GilbertPartenaire - email: gilbert.partenaire@nicolas.com - encrypted_password: "$2a$10$UtWcIYMd2aOtQjw6OFL4cuMV1MB20Bfs/opzJDqWXqu8woUo.2cLu" - reset_password_token: - reset_password_sent_at: - remember_created_at: - sign_in_count: 0 - current_sign_in_at: - last_sign_in_at: - current_sign_in_ip: - last_sign_in_ip: - confirmation_token: - confirmed_at: 2016-04-04 15:18:14.124111000 Z - confirmation_sent_at: 2016-04-04 15:17:12.522028000 Z - unconfirmed_email: - failed_attempts: 0 - unlock_token: - locked_at: - created_at: 2016-04-04 15:17:12.522028000 Z - updated_at: 2016-04-04 15:17:12.522028000 Z - is_allow_contact: true - group_id: 1 - stp_customer_id: cus_8CzQK5uXPeyh4K - slug: gilbertpartenaire - is_active: true - provider: - uid: - auth_token: - merged_at: - is_allow_newsletter: true - -user_5: - id: 5 - username: vlonchamp - email: vanessa.lonchamp@sfr.fr - encrypted_password: "$2a$10$HOEk.QyGwpd9nsk2gVXGSuAxig9jMrNFHVqYMW1.Sp41EtN7rdBbG" - reset_password_token: - reset_password_sent_at: - remember_created_at: - sign_in_count: 1 - current_sign_in_at: 2016-04-04 15:34:23.343596000 Z - last_sign_in_at: 2016-04-04 15:34:23.343596000 Z - current_sign_in_ip: 37.64.230.6 - last_sign_in_ip: 37.67.211.2 - confirmation_token: 59cfd407491c4e1d95a9f91f81e710a62a83a6fd7171ad22823b4c4395312c4d - confirmed_at: 2016-04-04 15:18:12.122101000 Z - confirmation_sent_at: 2016-04-04 15:14:08.599603000 Z - unconfirmed_email: - failed_attempts: 0 - unlock_token: - locked_at: - created_at: 2016-04-04 15:14:08.563152000 Z - updated_at: 2016-04-04 15:34:23.344613000 Z - is_allow_contact: true - group_id: 2 - stp_customer_id: cus_8CzNtM08NVlSGN - slug: vlonchamp - is_active: true - provider: - uid: - auth_token: - merged_at: - is_allow_newsletter: true - user_3: id: 3 username: pdurand @@ -155,7 +86,6 @@ user_3: updated_at: 2016-04-05 08:35:05.678582000 Z is_allow_contact: false group_id: 1 - stp_customer_id: cus_8CzHcwBJtlA3IL slug: pdurand is_active: true provider: @@ -164,32 +94,63 @@ user_3: merged_at: is_allow_newsletter: false -user_1: - id: 1 - username: admin - email: admin@fab-manager.com - encrypted_password: "$2a$10$LtQ2OggropcXpmcsPTEPruuGZrwuFYGOo8qjh.po91YDna/K4/Bbe" +user_4: + id: 4 + username: kdumas + email: kevin.dumas@orange.fr + encrypted_password: "$2a$10$N6Q4SHkkUtwlnMNFvN6nF.rkmLFTIPsARk7xEuR1Dws7Dy2sSrSOW" reset_password_token: reset_password_sent_at: remember_created_at: - sign_in_count: 8 - current_sign_in_at: 2016-04-05 08:36:08.361260000 Z - last_sign_in_at: 2016-04-05 08:34:28.227054000 Z - current_sign_in_ip: 127.0.0.1 - last_sign_in_ip: 127.0.0.1 + sign_in_count: 0 + current_sign_in_at: + last_sign_in_at: + current_sign_in_ip: + last_sign_in_ip: confirmation_token: - confirmed_at: 2016-04-05 08:40:21.514533000 Z - confirmation_sent_at: 2001-01-01 14:11:33.852719000 Z + confirmed_at: 2016-04-04 15:11:02.968494000 Z + confirmation_sent_at: 2016-04-04 15:10:42.376191000 Z unconfirmed_email: failed_attempts: 0 unlock_token: locked_at: - created_at: 2001-01-01 14:11:33.852719000 Z - updated_at: 2016-04-05 08:36:08.362215000 Z + created_at: 2016-04-04 15:10:42.340868000 Z + updated_at: 2016-04-04 15:11:02.969182000 Z is_allow_contact: true - group_id: 3 - stp_customer_id: cus_8CyNk3UTi8lvCc - slug: admin + group_id: 2 + slug: kdumas + is_active: true + provider: + uid: + auth_token: + merged_at: + is_allow_newsletter: false + +user_5: + id: 5 + username: vlonchamp + email: vanessa.lonchamp@sfr.fr + encrypted_password: "$2a$10$HOEk.QyGwpd9nsk2gVXGSuAxig9jMrNFHVqYMW1.Sp41EtN7rdBbG" + reset_password_token: + reset_password_sent_at: + remember_created_at: + sign_in_count: 1 + current_sign_in_at: 2016-04-04 15:34:23.343596000 Z + last_sign_in_at: 2016-04-04 15:34:23.343596000 Z + current_sign_in_ip: 37.64.230.6 + last_sign_in_ip: 37.67.211.2 + confirmation_token: 59cfd407491c4e1d95a9f91f81e710a62a83a6fd7171ad22823b4c4395312c4d + confirmed_at: 2016-04-04 15:18:12.122101000 Z + confirmation_sent_at: 2016-04-04 15:14:08.599603000 Z + unconfirmed_email: + failed_attempts: 0 + unlock_token: + locked_at: + created_at: 2016-04-04 15:14:08.563152000 Z + updated_at: 2016-04-04 15:34:23.344613000 Z + is_allow_contact: true + group_id: 2 + slug: vlonchamp is_active: true provider: uid: @@ -197,6 +158,37 @@ user_1: merged_at: is_allow_newsletter: true +user_6: + id: 6 + username: GilbertPartenaire + email: gilbert.partenaire@nicolas.com + encrypted_password: "$2a$10$UtWcIYMd2aOtQjw6OFL4cuMV1MB20Bfs/opzJDqWXqu8woUo.2cLu" + reset_password_token: + reset_password_sent_at: + remember_created_at: + sign_in_count: 0 + current_sign_in_at: + last_sign_in_at: + current_sign_in_ip: + last_sign_in_ip: + confirmation_token: + confirmed_at: 2016-04-04 15:18:14.124111000 Z + confirmation_sent_at: 2016-04-04 15:17:12.522028000 Z + unconfirmed_email: + failed_attempts: 0 + unlock_token: + locked_at: + created_at: 2016-04-04 15:17:12.522028000 Z + updated_at: 2016-04-04 15:17:12.522028000 Z + is_allow_contact: true + group_id: 1 + slug: gilbertpartenaire + is_active: true + provider: + uid: + auth_token: + merged_at: + is_allow_newsletter: true user_7: id: 7 @@ -222,7 +214,6 @@ user_7: updated_at: 2016-04-07 11:00:37.643112000 Z is_allow_contact: true group_id: 1 - stp_customer_id: cus_8E2ys9zDZgetWX slug: lseguin is_active: true provider: @@ -255,7 +246,6 @@ user_8: updated_at: 2021-01-04 14:36:39.729052932 Z is_allow_contact: true group_id: 1 - stp_customer_id: cus_IhIynmoJbzLpwX slug: atiermoulin is_active: true provider: diff --git a/test/integration/events/as_admin_test.rb b/test/integration/events/as_admin_test.rb index 0228428d3..2dfd2bd8a 100644 --- a/test/integration/events/as_admin_test.rb +++ b/test/integration/events/as_admin_test.rb @@ -64,8 +64,8 @@ module Events # Now, let's make a reservation on this event post '/api/reservations', params: { + customer_id: User.find_by(username: 'pdurand').id, reservation: { - user_id: User.find_by(username: 'pdurand').id, reservable_id: e.id, reservable_type: 'Event', nb_reserve_places: 2, @@ -158,8 +158,8 @@ module Events # Now, let's make a reservation on this event post '/api/reservations', params: { + customer_id: User.find_by(username: 'lseguin').id, reservation: { - user_id: User.find_by(username: 'lseguin').id, reservable_id: e.id, reservable_type: 'Event', nb_reserve_places: 4, diff --git a/test/integration/events/as_user_test.rb b/test/integration/events/as_user_test.rb index 6ad6095be..73bee6418 100644 --- a/test/integration/events/as_user_test.rb +++ b/test/integration/events/as_user_test.rb @@ -29,9 +29,9 @@ module Events post '/api/stripe/confirm_payment', params: { payment_method_id: stripe_payment_method, + customer_id: User.find_by(username: 'vlonchamp').id, cart_items: { reservation: { - user_id: User.find_by(username: 'vlonchamp').id, reservable_id: radio.id, reservable_type: 'Event', nb_reserve_places: 2, @@ -78,7 +78,7 @@ module Events # invoice assertions invoice = reservation.invoice - refute invoice.stp_payment_intent_id.blank? + refute invoice.payment_gateway_object.blank? refute invoice.total.blank? assert_equal 43_350, invoice.total # total minus coupon @@ -94,7 +94,7 @@ module Events assert_invoice_pdf invoice VCR.use_cassette('reserve_event_with_many_prices_and_payment_means_retrieve_invoice_from_stripe') do - stp_intent = Stripe::PaymentIntent.retrieve(invoice.stp_payment_intent_id, api_key: Setting.get('stripe_secret_key')) + stp_intent = invoice.payment_gateway_object.gateway_object.retrieve assert_equal stp_intent.amount, (invoice.total - invoice.wallet_amount) # total minus coupon minus wallet = amount really payed by the user end diff --git a/test/integration/prices/compute_test.rb b/test/integration/prices/compute_test.rb index ad64e44cd..c198a4934 100644 --- a/test/integration/prices/compute_test.rb +++ b/test/integration/prices/compute_test.rb @@ -14,8 +14,8 @@ module Prices post '/api/prices/compute', params: { + customer_id: user.id, reservation: { - user_id: user.id, reservable_id: printer_training.id, reservable_type: printer_training.class.name, slots_attributes: [ @@ -49,11 +49,10 @@ module Prices post '/api/prices/compute', params: { + customer_id: user.id, reservation: { - user_id: user.id, reservable_id: laser.id, reservable_type: laser.class.name, - plan_id: plan.id, slots_attributes: [ { availability_id: availability.id, @@ -68,6 +67,9 @@ module Prices start_at: (availability.start_at + 1.hour).strftime('%Y-%m-%d %H:%M:%S.%9N Z') } ] + }, + subscription: { + plan_id: plan.id } }.to_json, headers: default_headers diff --git a/test/integration/reservations/create_as_admin_test.rb b/test/integration/reservations/create_as_admin_test.rb index 26b06a1f1..cc347468c 100644 --- a/test/integration/reservations/create_as_admin_test.rb +++ b/test/integration/reservations/create_as_admin_test.rb @@ -19,18 +19,20 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest invoice_items_count = InvoiceItem.count users_credit_count = UsersCredit.count - post reservations_path, params: { reservation: { - user_id: @user_without_subscription.id, - reservable_id: machine.id, - reservable_type: machine.class.name, - slots_attributes: [ - { - start_at: availability.start_at.to_s(:iso8601), - end_at: (availability.start_at + 1.hour).to_s(:iso8601), - availability_id: availability.id - } - ] - } }.to_json, headers: default_headers + post reservations_path, params: { + customer_id: @user_without_subscription.id, + reservation: { + reservable_id: machine.id, + reservable_type: machine.class.name, + slots_attributes: [ + { + start_at: availability.start_at.to_s(:iso8601), + end_at: (availability.start_at + 1.hour).to_s(:iso8601), + availability_id: availability.id + } + ] + } + }.to_json, headers: default_headers # general assertions assert_equal 201, response.status @@ -52,7 +54,7 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - assert invoice.stp_payment_intent_id.blank? + assert invoice.payment_gateway_object.blank? refute invoice.total.blank? # invoice_items assertions @@ -76,18 +78,20 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest invoice_count = Invoice.count invoice_items_count = InvoiceItem.count - post reservations_path, params: { reservation: { - user_id: @user_without_subscription.id, - reservable_id: training.id, - reservable_type: training.class.name, - slots_attributes: [ - { - start_at: availability.start_at.to_s(:iso8601), - end_at: (availability.start_at + 1.hour).to_s(:iso8601), - availability_id: availability.id - } - ] - } }.to_json, headers: default_headers + post reservations_path, params: { + customer_id: @user_without_subscription.id, + reservation: { + reservable_id: training.id, + reservable_type: training.class.name, + slots_attributes: [ + { + start_at: availability.start_at.to_s(:iso8601), + end_at: (availability.start_at + 1.hour).to_s(:iso8601), + availability_id: availability.id + } + ] + } + }.to_json, headers: default_headers # general assertions assert_equal 201, response.status @@ -108,7 +112,7 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - assert invoice.stp_payment_intent_id.blank? + assert invoice.payment_gateway_object.blank? refute invoice.total.blank? # invoice_items invoice_item = InvoiceItem.last @@ -133,23 +137,25 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest invoice_items_count = InvoiceItem.count users_credit_count = UsersCredit.count - post reservations_path, params: { reservation: { - user_id: @user_with_subscription.id, - reservable_id: machine.id, - reservable_type: machine.class.name, - slots_attributes: [ - { - start_at: availability.start_at.to_s(:iso8601), - end_at: (availability.start_at + 1.hour).to_s(:iso8601), - availability_id: availability.id - }, - { - start_at: (availability.start_at + 1.hour).to_s(:iso8601), - end_at: (availability.start_at + 2.hours).to_s(:iso8601), - availability_id: availability.id - } - ] - } }.to_json, headers: default_headers + post reservations_path, params: { + customer_id: @user_with_subscription.id, + reservation: { + reservable_id: machine.id, + reservable_type: machine.class.name, + slots_attributes: [ + { + start_at: availability.start_at.to_s(:iso8601), + end_at: (availability.start_at + 1.hour).to_s(:iso8601), + availability_id: availability.id + }, + { + start_at: (availability.start_at + 1.hour).to_s(:iso8601), + end_at: (availability.start_at + 2.hours).to_s(:iso8601), + availability_id: availability.id + } + ] + } + }.to_json, headers: default_headers # general assertions assert_equal 201, response.status @@ -172,7 +178,7 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - assert invoice.stp_payment_intent_id.blank? + assert invoice.payment_gateway_object.blank? refute invoice.total.blank? # invoice_items assertions @@ -206,18 +212,20 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest invoice_items_count = InvoiceItem.count users_credit_count = UsersCredit.count - post reservations_path, params: { reservation: { - user_id: @vlonchamp.id, - reservable_id: machine.id, - reservable_type: machine.class.name, - slots_attributes: [ - { - start_at: availability.start_at.to_s(:iso8601), - end_at: (availability.start_at + 1.hour).to_s(:iso8601), - availability_id: availability.id - } - ] - } }.to_json, headers: default_headers + post reservations_path, params: { + customer_id: @vlonchamp.id, + reservation: { + reservable_id: machine.id, + reservable_type: machine.class.name, + slots_attributes: [ + { + start_at: availability.start_at.to_s(:iso8601), + end_at: (availability.start_at + 1.hour).to_s(:iso8601), + availability_id: availability.id + } + ] + } + }.to_json, headers: default_headers # general assertions assert_equal 201, response.status @@ -239,7 +247,7 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - assert invoice.stp_payment_intent_id.blank? + assert invoice.payment_gateway_object.blank? refute invoice.total.blank? # invoice_items assertions @@ -276,19 +284,23 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest users_credit_count = UsersCredit.count wallet_transactions_count = WalletTransaction.count - post reservations_path, params: { reservation: { - user_id: @vlonchamp.id, - reservable_id: machine.id, - reservable_type: machine.class.name, - plan_id: plan.id, - slots_attributes: [ - { - start_at: availability.start_at.to_s(:iso8601), - end_at: (availability.start_at + 1.hour).to_s(:iso8601), - availability_id: availability.id - } - ] - } }.to_json, headers: default_headers + post reservations_path, params: { + customer_id: @vlonchamp.id, + subscription: { + plan_id: plan.id, + }, + reservation: { + reservable_id: machine.id, + reservable_type: machine.class.name, + slots_attributes: [ + { + start_at: availability.start_at.to_s(:iso8601), + end_at: (availability.start_at + 1.hour).to_s(:iso8601), + availability_id: availability.id + } + ] + } + }.to_json, headers: default_headers # general assertions assert_equal 201, response.status @@ -312,7 +324,7 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - assert invoice.stp_payment_intent_id.blank? + assert invoice.payment_gateway_object.blank? refute invoice.total.blank? assert_equal invoice.total, 2000 @@ -343,18 +355,20 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest invoice_items_count = InvoiceItem.count users_credit_count = UsersCredit.count - post reservations_path, params: { reservation: { - user_id: @vlonchamp.id, - reservable_id: machine.id, - reservable_type: machine.class.name, - slots_attributes: [ - { - start_at: availability.start_at.to_s(:iso8601), - end_at: (availability.start_at + 1.hour).to_s(:iso8601), - availability_id: availability.id - } - ] - } }.to_json, headers: default_headers + post reservations_path, params: { + customer_id: @vlonchamp.id, + reservation: { + reservable_id: machine.id, + reservable_type: machine.class.name, + slots_attributes: [ + { + start_at: availability.start_at.to_s(:iso8601), + end_at: (availability.start_at + 1.hour).to_s(:iso8601), + availability_id: availability.id + } + ] + } + }.to_json, headers: default_headers # general assertions assert_equal 201, response.status @@ -386,20 +400,24 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest invoice_items_count = InvoiceItem.count users_credit_count = UsersCredit.count - post reservations_path, params: { reservation: { - user_id: @user_without_subscription.id, - plan_id: plan.id, - reservable_id: training.id, - reservable_type: training.class.name, - slots_attributes: [ - { - start_at: availability.start_at.to_s(:iso8601), - end_at: (availability.start_at + 1.hour).to_s(:iso8601), - offered: false, - availability_id: availability.id - } - ] - } }.to_json, headers: default_headers + post reservations_path, params: { + customer_id: @user_without_subscription.id, + reservation: { + reservable_id: training.id, + reservable_type: training.class.name, + slots_attributes: [ + { + start_at: availability.start_at.to_s(:iso8601), + end_at: (availability.start_at + 1.hour).to_s(:iso8601), + offered: false, + availability_id: availability.id + } + ] + }, + subscription: { + plan_id: plan.id, + } + }.to_json, headers: default_headers # general assertions assert_equal 201, response.status @@ -431,7 +449,7 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - assert invoice.stp_payment_intent_id.blank? + assert invoice.payment_gateway_object.blank? refute invoice.total.blank? assert_equal plan.amount, invoice.total @@ -463,21 +481,25 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest plan = Plan.find_by(group_id: @user_without_subscription.group.id, type: 'Plan', base_name: 'Abonnement mensualisable') VCR.use_cassette('reservations_admin_training_subscription_with_payment_schedule') do - post reservations_path, params: { reservation: { - user_id: @user_without_subscription.id, + post reservations_path, params: { payment_method: 'check', - reservable_id: training.id, - reservable_type: training.class.name, - slots_attributes: [ - { - start_at: availability.start_at.to_s(:iso8601), - end_at: (availability.start_at + 1.hour).to_s(:iso8601), - availability_id: availability.id - } - ], - plan_id: plan.id, - payment_schedule: true - } }.to_json, headers: default_headers + payment_schedule: true, + customer_id: @user_without_subscription.id, + reservation: { + reservable_id: training.id, + reservable_type: training.class.name, + slots_attributes: [ + { + start_at: availability.start_at.to_s(:iso8601), + end_at: (availability.start_at + 1.hour).to_s(:iso8601), + availability_id: availability.id + } + ] + }, + subscription: { + plan_id: plan.id + } + }.to_json, headers: default_headers end # get the objects @@ -513,8 +535,7 @@ class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest # payment schedule assertions assert_not_nil payment_schedule.reference assert_equal 'check', payment_schedule.payment_method - assert_nil payment_schedule.stp_subscription_id - assert_nil payment_schedule.stp_setup_intent_id # FIXME + assert_empty payment_schedule.payment_gateway_objects assert_nil payment_schedule.wallet_transaction assert_nil payment_schedule.wallet_amount assert_nil payment_schedule.coupon_id diff --git a/test/integration/reservations/create_test.rb b/test/integration/reservations/create_test.rb index b2e356dd8..1727f1da2 100644 --- a/test/integration/reservations/create_test.rb +++ b/test/integration/reservations/create_test.rb @@ -61,7 +61,7 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - refute invoice.stp_payment_intent_id.blank? + refute invoice.payment_gateway_object.blank? refute invoice.total.blank? assert invoice.check_footprint @@ -177,7 +177,7 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - refute invoice.stp_payment_intent_id.blank? + refute invoice.payment_gateway_object.blank? refute invoice.total.blank? assert invoice.check_footprint @@ -253,7 +253,7 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - refute invoice.stp_payment_intent_id.blank? + refute invoice.payment_gateway_object.blank? refute invoice.total.blank? assert invoice.check_footprint @@ -328,7 +328,7 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - assert invoice.stp_payment_intent_id.blank? + assert invoice.payment_gateway_object.blank? refute invoice.total.blank? assert invoice.check_footprint @@ -367,11 +367,10 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest params: { payment_method_id: stripe_payment_method, cart_items: { + customer_id: @vlonchamp.id, reservation: { - user_id: @vlonchamp.id, reservable_id: machine.id, reservable_type: machine.class.name, - card_token: stripe_payment_method, slots_attributes: [ { start_at: availability.start_at.to_s(:iso8601), @@ -407,7 +406,7 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - refute invoice.stp_payment_intent_id.blank? + refute invoice.payment_gateway_object.blank? refute invoice.total.blank? assert invoice.check_footprint @@ -454,7 +453,6 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest reservation: { reservable_id: training.id, reservable_type: training.class.name, - plan_id: plan.id, slots_attributes: [ { start_at: availability.start_at.to_s(:iso8601), @@ -462,6 +460,9 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest availability_id: availability.id } ] + }, + subscription: { + plan_id: plan.id } } }.to_json, headers: default_headers @@ -490,7 +491,7 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - refute invoice.stp_payment_intent_id.blank? + refute invoice.payment_gateway_object.blank? refute invoice.total.blank? assert_equal invoice.total, 2000 assert invoice.check_footprint @@ -538,7 +539,9 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest end_at: (availability.start_at + 1.hour).to_s(:iso8601), availability_id: availability.id } - ], + ] + }, + subscription: { plan_id: plan.id }, coupon_code: 'SUNNYFABLAB' @@ -568,7 +571,7 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest # invoice assertions invoice = reservation.invoice - refute invoice.stp_payment_intent_id.blank? + refute invoice.payment_gateway_object.blank? refute invoice.total.blank? assert invoice.check_footprint @@ -595,7 +598,7 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest assert_invoice_pdf invoice VCR.use_cassette('reservations_machine_and_plan_using_coupon_retrieve_invoice_from_stripe') do - stp_intent = Stripe::PaymentIntent.retrieve(invoice.stp_payment_intent_id, api_key: Setting.get('stripe_secret_key')) + stp_intent = invoice.payment_gateway_object.gateway_object.retrieve assert_equal stp_intent.amount, invoice.total end @@ -620,8 +623,8 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest params: { payment_method_id: stripe_payment_method, cart_items: { + customer_id: @user_without_subscription.id, reservation: { - user_id: @user_without_subscription.id, reservable_id: training.id, reservable_type: training.class.name, card_token: stripe_payment_method, @@ -696,6 +699,7 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest params: { setup_intent_id: setup_intent[:id], cart_items: { + payment_schedule: true, reservation: { reservable_id: training.id, reservable_type: training.class.name, @@ -706,8 +710,9 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest availability_id: availability.id } ], + }, + subscription: { plan_id: plan.id, - payment_schedule: true } } }.to_json, headers: default_headers @@ -791,9 +796,11 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest setup_intent_id: setup_intent[:id], cart_items: { coupon_code: 'GIME3EUR', - reservation: { + payment_schedule: true, + subscription: { plan_id: plan.id, - payment_schedule: true, + }, + reservation: { reservable_id: machine.id, reservable_type: machine.class.name, slots_attributes: [ @@ -838,9 +845,9 @@ class Reservations::CreateTest < ActionDispatch::IntegrationTest # payment schedule assertions assert_not_nil payment_schedule.reference - assert_equal 'stripe', payment_schedule.payment_method - assert_not_nil payment_schedule.stp_subscription_id - assert_not_nil payment_schedule.stp_setup_intent_id # FIXME + assert_equal 'card', payment_schedule.payment_method + assert_equal 2, payment_schedule.payment_gateway_objects.count + assert_not_nil payment_schedule.gateway_payment_mean assert_not_nil payment_schedule.wallet_transaction assert_equal payment_schedule.ordered_items.first.amount, payment_schedule.wallet_amount assert_equal Coupon.find_by(code: 'GIME3EUR').id, payment_schedule.coupon_id diff --git a/test/integration/subscriptions/create_as_admin_test.rb b/test/integration/subscriptions/create_as_admin_test.rb index 8a3b96ddc..898b2ea4d 100644 --- a/test/integration/subscriptions/create_as_admin_test.rb +++ b/test/integration/subscriptions/create_as_admin_test.rb @@ -94,10 +94,10 @@ class Subscriptions::CreateAsAdminTest < ActionDispatch::IntegrationTest params: { setup_intent_id: setup_intent[:id], cart_items: { + customer_id: user.id, subscription: { plan_id: plan.id, payment_schedule: true, - user_id: user.id, payment_method: 'stripe' } } diff --git a/test/integration/subscriptions/renew_as_admin_test.rb b/test/integration/subscriptions/renew_as_admin_test.rb index 92adf17fd..ca11f82fa 100644 --- a/test/integration/subscriptions/renew_as_admin_test.rb +++ b/test/integration/subscriptions/renew_as_admin_test.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'test_helper' + class Subscriptions::RenewAsAdminTest < ActionDispatch::IntegrationTest setup do @admin = User.find_by(username: 'admin')