mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-20 14:54:15 +01:00
optimized the load time of the payment schedules list
From now, we no longer retrieve the client_secret directly from the API/list but from a specialized component which ask API/get_item. This highly decrease the laod time needed to fetch API/list
This commit is contained in:
parent
bfb1a1c3f9
commit
effe5c7ba9
@ -1,6 +1,7 @@
|
|||||||
# Changelog Fab-manager
|
# Changelog Fab-manager
|
||||||
|
|
||||||
- Updated caniuse db
|
- Updated caniuse db
|
||||||
|
- Optimized the load time of the payment schedules list
|
||||||
|
|
||||||
# v5.3.0 2021 December 29
|
# v5.3.0 2021 December 29
|
||||||
|
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
class API::PaymentSchedulesController < API::ApiController
|
class API::PaymentSchedulesController < API::ApiController
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_payment_schedule, only: %i[download cancel]
|
before_action :set_payment_schedule, only: %i[download cancel]
|
||||||
before_action :set_payment_schedule_item, only: %i[cash_check refresh_item pay_item]
|
before_action :set_payment_schedule_item, only: %i[show_item cash_check refresh_item pay_item]
|
||||||
|
|
||||||
|
# retrieve all payment schedules for the current user, paginated
|
||||||
def index
|
def index
|
||||||
@payment_schedules = PaymentSchedule.where('invoicing_profile_id = ?', current_user.invoicing_profile.id)
|
@payment_schedules = PaymentSchedule.where('invoicing_profile_id = ?', current_user.invoicing_profile.id)
|
||||||
.includes(:invoicing_profile, :payment_schedule_items, :payment_schedule_objects)
|
.includes(:invoicing_profile, :payment_schedule_items, :payment_schedule_objects)
|
||||||
@ -15,6 +16,7 @@ class API::PaymentSchedulesController < API::ApiController
|
|||||||
.per(params[:size])
|
.per(params[:size])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# retrieve all payment schedules for all users. Filtering is supported
|
||||||
def list
|
def list
|
||||||
authorize PaymentSchedule
|
authorize PaymentSchedule
|
||||||
|
|
||||||
@ -62,6 +64,11 @@ class API::PaymentSchedulesController < API::ApiController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show_item
|
||||||
|
authorize @payment_schedule_item.payment_schedule
|
||||||
|
render json: @payment_schedule_item, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
def cancel
|
def cancel
|
||||||
authorize @payment_schedule
|
authorize @payment_schedule
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import {
|
|||||||
CancelScheduleResponse,
|
CancelScheduleResponse,
|
||||||
CashCheckResponse, PayItemResponse,
|
CashCheckResponse, PayItemResponse,
|
||||||
PaymentSchedule,
|
PaymentSchedule,
|
||||||
PaymentScheduleIndexRequest, RefreshItemResponse
|
PaymentScheduleIndexRequest, PaymentScheduleItem, RefreshItemResponse
|
||||||
} from '../models/payment-schedule';
|
} from '../models/payment-schedule';
|
||||||
|
|
||||||
export default class PaymentScheduleAPI {
|
export default class PaymentScheduleAPI {
|
||||||
@ -23,6 +23,11 @@ export default class PaymentScheduleAPI {
|
|||||||
return res?.data;
|
return res?.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async getItem (paymentScheduleItemId: number): Promise<PaymentScheduleItem> {
|
||||||
|
const res: AxiosResponse = await apiClient.get(`/api/payment_schedules/items/${paymentScheduleItemId}`);
|
||||||
|
return res?.data;
|
||||||
|
}
|
||||||
|
|
||||||
static async refreshItem (paymentScheduleItemId: number): Promise<RefreshItemResponse> {
|
static async refreshItem (paymentScheduleItemId: number): Promise<RefreshItemResponse> {
|
||||||
const res: AxiosResponse = await apiClient.post(`/api/payment_schedules/items/${paymentScheduleItemId}/refresh_item`);
|
const res: AxiosResponse = await apiClient.post(`/api/payment_schedules/items/${paymentScheduleItemId}/refresh_item`);
|
||||||
return res?.data;
|
return res?.data;
|
||||||
|
@ -11,6 +11,7 @@ import { User, UserRole } from '../../models/user';
|
|||||||
import { PaymentSchedule, PaymentScheduleItem, PaymentScheduleItemState } from '../../models/payment-schedule';
|
import { PaymentSchedule, PaymentScheduleItem, PaymentScheduleItemState } from '../../models/payment-schedule';
|
||||||
import PaymentScheduleAPI from '../../api/payment-schedule';
|
import PaymentScheduleAPI from '../../api/payment-schedule';
|
||||||
import FormatLib from '../../lib/format';
|
import FormatLib from '../../lib/format';
|
||||||
|
import { StripeConfirmModal } from '../payment/stripe/stripe-confirm-modal';
|
||||||
|
|
||||||
interface PaymentSchedulesTableProps {
|
interface PaymentSchedulesTableProps {
|
||||||
paymentSchedules: Array<PaymentSchedule>,
|
paymentSchedules: Array<PaymentSchedule>,
|
||||||
@ -412,14 +413,10 @@ const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({
|
|||||||
{t('app.shared.schedules_table.confirm_cancel_subscription')}
|
{t('app.shared.schedules_table.confirm_cancel_subscription')}
|
||||||
</FabModal>
|
</FabModal>
|
||||||
<StripeElements>
|
<StripeElements>
|
||||||
<FabModal title={t('app.shared.schedules_table.resolve_action')}
|
{tempDeadline && <StripeConfirmModal isOpen={showResolveAction}
|
||||||
isOpen={showResolveAction}
|
|
||||||
toggleModal={toggleResolveActionModal}
|
toggleModal={toggleResolveActionModal}
|
||||||
onConfirm={afterAction}
|
onSuccess={afterAction}
|
||||||
confirmButton={t('app.shared.schedules_table.ok_button')}
|
paymentScheduleItemId={tempDeadline.id} />}
|
||||||
preventConfirm={isConfirmActionDisabled}>
|
|
||||||
{tempDeadline && <StripeConfirm clientSecret={tempDeadline.client_secret} onResponse={toggleConfirmActionButton} />}
|
|
||||||
</FabModal>
|
|
||||||
{tempSchedule && <UpdateCardModal isOpen={showUpdateCard}
|
{tempSchedule && <UpdateCardModal isOpen={showUpdateCard}
|
||||||
toggleModal={toggleUpdateCardModal}
|
toggleModal={toggleUpdateCardModal}
|
||||||
operator={operator}
|
operator={operator}
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
import { StripeConfirm } from './stripe-confirm';
|
||||||
|
import { FabModal } from '../../base/fab-modal';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import PaymentScheduleAPI from '../../../api/payment-schedule';
|
||||||
|
import { PaymentScheduleItem } from '../../../models/payment-schedule';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
interface StripeConfirmModalProps {
|
||||||
|
isOpen: boolean,
|
||||||
|
toggleModal: () => void,
|
||||||
|
onSuccess: () => void,
|
||||||
|
paymentScheduleItemId: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modal dialog that trigger a 3D secure confirmation for the given payment schedule item (deadline for a payment schedule).
|
||||||
|
*/
|
||||||
|
export const StripeConfirmModal: React.FC<StripeConfirmModalProps> = ({ isOpen, toggleModal, onSuccess, paymentScheduleItemId }) => {
|
||||||
|
const { t } = useTranslation('shared');
|
||||||
|
|
||||||
|
const [item, setItem] = useState<PaymentScheduleItem>(null);
|
||||||
|
const [isPending, setIsPending] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
PaymentScheduleAPI.getItem(paymentScheduleItemId).then(data => {
|
||||||
|
setItem(data);
|
||||||
|
});
|
||||||
|
}, [paymentScheduleItemId]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback triggered when the confirm button was clicked in the modal.
|
||||||
|
*/
|
||||||
|
const onConfirmed = (): void => {
|
||||||
|
togglePending();
|
||||||
|
onSuccess();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable the confirm button of the "action" modal
|
||||||
|
*/
|
||||||
|
const togglePending = (): void => {
|
||||||
|
setIsPending(!isPending);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FabModal title={t('app.shared.schedules_table.resolve_action')}
|
||||||
|
isOpen={isOpen}
|
||||||
|
toggleModal={toggleModal}
|
||||||
|
onConfirm={onConfirmed}
|
||||||
|
confirmButton={t('app.shared.schedules_table.ok_button')}
|
||||||
|
preventConfirm={isPending}>
|
||||||
|
{item && <StripeConfirm clientSecret={item.client_secret} onResponse={togglePending} />}
|
||||||
|
</FabModal>
|
||||||
|
);
|
||||||
|
};
|
@ -35,7 +35,7 @@ const EditPlanCategoryComponent: React.FC<EditPlanCategoryProps> = ({ onSuccess,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The edit has been confirmed by the user.
|
* The edit has been confirmed by the user.
|
||||||
* Call the API to trigger the update of the temporary set plan-category
|
* Call the API to trigger the update of the temporary set plan-category.
|
||||||
*/
|
*/
|
||||||
const onEditConfirmed = (): void => {
|
const onEditConfirmed = (): void => {
|
||||||
PlanCategoryAPI.update(tempCategory).then((updatedCategory) => {
|
PlanCategoryAPI.update(tempCategory).then((updatedCategory) => {
|
||||||
|
@ -14,9 +14,10 @@ class PaymentScheduleItem < Footprintable
|
|||||||
|
|
||||||
def payment_intent
|
def payment_intent
|
||||||
return unless payment_gateway_object
|
return unless payment_gateway_object
|
||||||
|
return unless payment_gateway_object.gateway_object.gateway == 'Stripe'
|
||||||
|
|
||||||
stp_invoice = payment_gateway_object.gateway_object.retrieve
|
stp_invoice = payment_gateway_object.gateway_object.retrieve
|
||||||
Stripe::PaymentIntent.retrieve(stp_invoice.payment_intent, api_key: Setting.get('stripe_secret_key')) # FIXME, maybe this is only used for stripe?
|
Stripe::PaymentIntent.retrieve(stp_invoice.payment_intent, api_key: Setting.get('stripe_secret_key'))
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.columns_out_of_footprint
|
def self.columns_out_of_footprint
|
||||||
|
@ -8,7 +8,7 @@ class PaymentSchedulePolicy < ApplicationPolicy
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
%w[refresh_item? download? pay_item?].each do |action|
|
%w[refresh_item? download? pay_item? show_item?].each do |action|
|
||||||
define_method action do
|
define_method action do
|
||||||
user.admin? || user.manager? || (record.invoicing_profile.user_id == user.id)
|
user.admin? || user.manager? || (record.invoicing_profile.user_id == user.id)
|
||||||
end
|
end
|
||||||
|
@ -24,7 +24,5 @@ if payment_schedule.gateway_subscription
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
json.items payment_schedule.payment_schedule_items do |item|
|
json.items payment_schedule.payment_schedule_items do |item|
|
||||||
json.extract! item, :id, :due_date, :state, :invoice_id, :payment_method
|
json.partial! 'api/payment_schedules/payment_schedule_item', item: item
|
||||||
json.amount item.amount / 100.00
|
|
||||||
json.client_secret item.payment_intent.client_secret if item.payment_gateway_object && item.state == 'requires_action'
|
|
||||||
end
|
end
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
json.extract! item, :id, :due_date, :state, :invoice_id, :payment_method
|
||||||
|
json.amount item.amount / 100.00
|
6
app/views/api/payment_schedules/show_item.json.jbuilder
Normal file
6
app/views/api/payment_schedules/show_item.json.jbuilder
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
json.partial! 'api/payment_schedules/payment_schedule_item', item: @payment_schedule_item
|
||||||
|
if @payment_schedule_item.payment_gateway_object && @payment_schedule_item.state == 'requires_action'
|
||||||
|
json.client_secret @payment_schedule_item.payment_intent.client_secret
|
||||||
|
end
|
@ -123,6 +123,7 @@ Rails.application.routes.draw do
|
|||||||
post 'list', action: 'list', on: :collection
|
post 'list', action: 'list', on: :collection
|
||||||
put 'cancel', on: :member
|
put 'cancel', on: :member
|
||||||
get 'download', on: :member
|
get 'download', on: :member
|
||||||
|
get 'items/:id', action: 'show_item', on: :collection
|
||||||
post 'items/:id/cash_check', action: 'cash_check', on: :collection
|
post 'items/:id/cash_check', action: 'cash_check', on: :collection
|
||||||
post 'items/:id/refresh_item', action: 'refresh_item', on: :collection
|
post 'items/:id/refresh_item', action: 'refresh_item', on: :collection
|
||||||
post 'items/:id/pay_item', action: 'pay_item', on: :collection
|
post 'items/:id/pay_item', action: 'pay_item', on: :collection
|
||||||
|
@ -29,5 +29,9 @@ class Payment::Item
|
|||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def gateway
|
||||||
|
klass[/^(PayZen|Stripe)::/, 1]
|
||||||
|
end
|
||||||
|
|
||||||
def retrieve(_id = nil, *_args); end
|
def retrieve(_id = nil, *_args); end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user