mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-29 18:52:22 +01:00
fixes for card payment
This commit is contained in:
parent
6c39191efa
commit
5941446a72
@ -23,7 +23,7 @@ class API::SubscriptionsController < API::ApiController
|
||||
.pay_and_save(@subscription, coupon: coupon_params[:coupon_code],
|
||||
invoice: true,
|
||||
schedule: params[:subscription][:payment_schedule],
|
||||
payment_method: params[:reservation][:payment_method])
|
||||
payment_method: params[:subscription][:payment_method])
|
||||
|
||||
if is_subscribe
|
||||
render :show, status: :created, location: @subscription
|
||||
|
@ -17,5 +17,4 @@ class SocialBotController < ActionController::Base
|
||||
puts "unknown bot request : #{request.original_url}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
@ -2,7 +2,7 @@
|
||||
* This component is a "card" publicly presenting the details of a plan
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { react2angular } from 'react2angular';
|
||||
import moment from 'moment';
|
||||
@ -19,13 +19,14 @@ declare var Fablab: IFablab;
|
||||
|
||||
interface PlanCardProps {
|
||||
plan: Plan,
|
||||
user: User,
|
||||
userId?: number,
|
||||
subscribedPlanId?: number,
|
||||
operator: User,
|
||||
isSelected: boolean,
|
||||
onSelectPlan: (plan: Plan) => void,
|
||||
}
|
||||
|
||||
const PlanCard: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan, isSelected }) => {
|
||||
const PlanCard: React.FC<PlanCardProps> = ({ plan, userId, subscribedPlanId, operator, onSelectPlan, isSelected }) => {
|
||||
const { t } = useTranslation('public');
|
||||
/**
|
||||
* Return the formatted localized amount of the given plan (eg. 20.5 => "20,50 €")
|
||||
@ -50,19 +51,19 @@ const PlanCard: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan,
|
||||
* Check if the user can subscribe to the current plan, for himself
|
||||
*/
|
||||
const canSubscribeForMe = (): boolean => {
|
||||
return operator?.role === UserRole.Member || (operator?.role === UserRole.Manager && user?.id === operator?.id)
|
||||
return operator?.role === UserRole.Member || (operator?.role === UserRole.Manager && userId === operator?.id)
|
||||
}
|
||||
/**
|
||||
* Check if the user can subscribe to the current plan, for someone else
|
||||
*/
|
||||
const canSubscribeForOther = (): boolean => {
|
||||
return operator?.role === UserRole.Admin || (operator?.role === UserRole.Manager && user?.id !== operator?.id)
|
||||
return operator?.role === UserRole.Admin || (operator?.role === UserRole.Manager && userId !== operator?.id)
|
||||
}
|
||||
/**
|
||||
* Check it the user has subscribed to this plan or not
|
||||
*/
|
||||
const hasSubscribedToThisPlan = (): boolean => {
|
||||
return user?.subscription?.plan?.id === plan.id;
|
||||
return subscribedPlanId === plan.id;
|
||||
}
|
||||
/**
|
||||
* Check if the plan has an attached file
|
||||
@ -102,18 +103,18 @@ const PlanCard: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan,
|
||||
{canSubscribeForMe() && <div className="cta-button">
|
||||
{!hasSubscribedToThisPlan() && <button className={`subscribe-button ${isSelected ? 'selected-card' : ''}`}
|
||||
onClick={handleSelectPlan}
|
||||
disabled={!_.isNil(user.subscription)}>
|
||||
{user && <span>{t('app.public.plans.i_choose_that_plan')}</span>}
|
||||
{!user && <span>{t('app.public.plans.i_subscribe_online')}</span>}
|
||||
disabled={!_.isNil(subscribedPlanId)}>
|
||||
{userId && <span>{t('app.public.plans.i_choose_that_plan')}</span>}
|
||||
{!userId && <span>{t('app.public.plans.i_subscribe_online')}</span>}
|
||||
</button>}
|
||||
{hasSubscribedToThisPlan() && <button className="subscribe-button" disabled>
|
||||
{hasSubscribedToThisPlan() && <button className="subscribe-button selected-card" disabled>
|
||||
{ t('app.public.plans.i_already_subscribed') }
|
||||
</button>}
|
||||
</div>}
|
||||
{canSubscribeForOther() && <div className="cta-button">
|
||||
<button className={`subscribe-button ${isSelected ? 'selected-card' : ''}`}
|
||||
onClick={handleSelectPlan}
|
||||
disabled={_.isNil(user)}>
|
||||
disabled={_.isNil(userId)}>
|
||||
<span>{ t('app.public.plans.i_choose_that_plan') }</span>
|
||||
</button>
|
||||
</div>}
|
||||
@ -122,12 +123,12 @@ const PlanCard: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan,
|
||||
);
|
||||
}
|
||||
|
||||
const PlanCardWrapper: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan, isSelected }) => {
|
||||
const PlanCardWrapper: React.FC<PlanCardProps> = ({ plan, userId, subscribedPlanId, operator, onSelectPlan, isSelected }) => {
|
||||
return (
|
||||
<Loader>
|
||||
<PlanCard plan={plan} user={user} operator={operator} isSelected={isSelected} onSelectPlan={onSelectPlan}/>
|
||||
<PlanCard plan={plan} userId={userId} subscribedPlanId={subscribedPlanId} operator={operator} isSelected={isSelected} onSelectPlan={onSelectPlan}/>
|
||||
</Loader>
|
||||
);
|
||||
}
|
||||
|
||||
Application.Components.component('planCard', react2angular(PlanCardWrapper, ['plan', 'user', 'operator', 'onSelectPlan', 'isSelected']));
|
||||
Application.Components.component('planCard', react2angular(PlanCardWrapper, ['plan', 'userId', 'subscribedPlanId', 'operator', 'onSelectPlan', 'isSelected']));
|
||||
|
@ -665,7 +665,9 @@ Application.Controllers.controller('ReserveMachineController', ['$scope', '$stat
|
||||
|
||||
if ($scope.selectedPlan) {
|
||||
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
if ($scope.ctrl.member.id === Auth._currentUser.id) {
|
||||
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
}
|
||||
$scope.plansAreShown = false;
|
||||
$scope.selectedPlan = null;
|
||||
}
|
||||
|
@ -167,7 +167,9 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
*/
|
||||
$scope.afterPayment = function () {
|
||||
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
if ($scope.ctrl.member.id === Auth._currentUser.id) {
|
||||
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
}
|
||||
$scope.paid.plan = angular.copy($scope.selectedPlan);
|
||||
$scope.selectedPlan = null;
|
||||
$scope.coupon.applied = null;
|
||||
|
@ -571,14 +571,18 @@ Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateP
|
||||
|
||||
if ($scope.selectedPlan) {
|
||||
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
if ($scope.ctrl.member.id === Auth._currentUser.id) {
|
||||
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
}
|
||||
$scope.plansAreShown = false;
|
||||
$scope.selectedPlan = null;
|
||||
}
|
||||
$scope.ctrl.member.training_credits = angular.copy(reservation.user.training_credits);
|
||||
$scope.ctrl.member.machine_credits = angular.copy(reservation.user.machine_credits);
|
||||
Auth._currentUser.training_credits = angular.copy(reservation.user.training_credits);
|
||||
Auth._currentUser.machine_credits = angular.copy(reservation.user.machine_credits);
|
||||
if ($scope.ctrl.member.id === Auth._currentUser.id) {
|
||||
Auth._currentUser.training_credits = angular.copy(reservation.user.training_credits);
|
||||
Auth._currentUser.machine_credits = angular.copy(reservation.user.machine_credits);
|
||||
}
|
||||
|
||||
refetchCalendar();
|
||||
};
|
||||
|
@ -361,14 +361,18 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
|
||||
|
||||
if ($scope.selectedPlan) {
|
||||
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
if ($scope.ctrl.member.id === Auth._currentUser.id) {
|
||||
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
}
|
||||
$scope.plansAreShown = false;
|
||||
$scope.selectedPlan = null;
|
||||
}
|
||||
$scope.ctrl.member.training_credits = angular.copy(reservation.user.training_credits);
|
||||
$scope.ctrl.member.machine_credits = angular.copy(reservation.user.machine_credits);
|
||||
Auth._currentUser.training_credits = angular.copy(reservation.user.training_credits);
|
||||
Auth._currentUser.machine_credits = angular.copy(reservation.user.machine_credits);
|
||||
if ($scope.ctrl.member.id === Auth._currentUser.id) {
|
||||
Auth._currentUser.training_credits = angular.copy(reservation.user.training_credits);
|
||||
Auth._currentUser.machine_credits = angular.copy(reservation.user.machine_credits);
|
||||
}
|
||||
|
||||
refetchCalendar();
|
||||
};
|
||||
|
@ -779,7 +779,7 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs',
|
||||
* Callback to process the local payment, triggered on button click
|
||||
*/
|
||||
$scope.ok = function () {
|
||||
if ($scope.method.payment_method === 'stripe') {
|
||||
if ($scope.schedule && $scope.method.payment_method === 'stripe') {
|
||||
return $scope.toggleStripeModal();
|
||||
}
|
||||
$scope.attempting = true;
|
||||
@ -843,10 +843,12 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs',
|
||||
*/
|
||||
const computeValidButtonName = function () {
|
||||
let method = '';
|
||||
if (AuthService.isAuthorized(['admin', 'manager']) && $rootScope.currentUser.id !== reservation.user_id) {
|
||||
method = $scope.method.payment_method;
|
||||
} else {
|
||||
method = 'stripe';
|
||||
if ($scope.schedule) {
|
||||
if (AuthService.isAuthorized(['admin', 'manager']) && $rootScope.currentUser.id !== reservation.user_id) {
|
||||
method = $scope.method.payment_method;
|
||||
} else {
|
||||
method = 'stripe';
|
||||
}
|
||||
}
|
||||
if ($scope.amount > 0) {
|
||||
return _t('app.shared.cart.confirm_payment_of_html', { METHOD: method, AMOUNT: $filter('currency')($scope.amount) });
|
||||
|
@ -6,18 +6,22 @@
|
||||
<div class="row row-centered padder">
|
||||
<div class="col-xs-12 col-md-12 col-lg-10 col-centered no-gutter">
|
||||
|
||||
<!-- ng-class directive center the last item if the list length is odd -->
|
||||
<div class="pricing-panel col-xs-6 col-md-6 col-lg-6 text-center"
|
||||
ng-class="{'col-md-12 col-lg-12':(plansGroup.plans.filter(filterDisabledPlans).length % 2 == 1 && key == plansGroup.plans.filter(filterDisabledPlans).length-1)}"
|
||||
ng-repeat="(key, plan) in plansGroup.plans.filter(filterDisabledPlans) | orderBy:'interval'">
|
||||
|
||||
<plan-card plan="plan"
|
||||
user="ctrl.member"
|
||||
operator="currentUser"
|
||||
on-select-plan="selectPlan"
|
||||
is-selected="isSelected(plan)">
|
||||
</plan-card>
|
||||
<div ng-repeat="(key, plan) in plansGroup.plans.filter(filterDisabledPlans) | orderBy:'interval'"
|
||||
ng-class-even="'row'">
|
||||
<div class="pricing-panel col-xs-12 col-md-6 col-lg-6 text-center"
|
||||
ng-class="{'col-md-12 col-lg-12':(plansGroup.plans.filter(filterDisabledPlans).length % 2 == 1 && key == plansGroup.plans.filter(filterDisabledPlans).length-1)}">
|
||||
<!-- ng-class directive center the last item if the list length is odd -->
|
||||
|
||||
<plan-card plan="plan"
|
||||
user-id="ctrl.member.id"
|
||||
subscribed-plan-id="ctrl.member.subscribed_plan.id"
|
||||
operator="currentUser"
|
||||
on-select-plan="selectPlan"
|
||||
is-selected="isSelected(plan)">
|
||||
</plan-card>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="m-t-lg btn btn-small btn-default pull-right" href="#" ng-click="doNotSubscribePlan($event)">{{ 'app.shared.plan_subscribe.do_not_subscribe' | translate }} <i class="fa fa-long-arrow-right"></i></a>
|
||||
|
@ -32,7 +32,8 @@
|
||||
ng-repeat="(key, plan) in plansGroup.plans.filter(filterDisabledPlans) | orderBy: '-ui_weight'">
|
||||
|
||||
<plan-card plan="plan"
|
||||
user="ctrl.member"
|
||||
user-id="ctrl.member.id"
|
||||
subscribed-plan-id="ctrl.member.subscribed_plan.id"
|
||||
operator="currentUser"
|
||||
on-select-plan="selectPlan"
|
||||
is-selected="isSelected(plan)">
|
||||
|
@ -21,6 +21,7 @@ class Subscription < ApplicationRecord
|
||||
|
||||
# @param invoice if true then only the subscription is payed, without reservation
|
||||
# if false then the subscription is payed with reservation
|
||||
# @param payment_method is only used for schedules
|
||||
def save_with_payment(operator_profile_id, invoice: true, coupon_code: nil, payment_intent_id: nil, schedule: nil, payment_method: nil)
|
||||
return false unless valid?
|
||||
|
||||
|
@ -15,7 +15,7 @@ class Subscriptions::Subscribe
|
||||
# @param invoice {Boolean}
|
||||
# @param payment_intent_id {String} from stripe
|
||||
# @param schedule {Boolean}
|
||||
# @param payment_method {String}
|
||||
# @param payment_method {String} only for schedules
|
||||
##
|
||||
def pay_and_save(subscription, coupon: nil, invoice: false, payment_intent_id: nil, schedule: false, payment_method: nil)
|
||||
return false if user_id.nil?
|
||||
|
Loading…
x
Reference in New Issue
Block a user