1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-19 13:54:25 +01:00

(bug) members are unable to buy prepaid-packs by wallet

This commit is contained in:
Sylvain 2022-01-18 17:03:16 +01:00
parent 28489e112c
commit 512828931f
3 changed files with 103 additions and 27 deletions

View File

@ -4,8 +4,9 @@
- Fix a bug: missing the Other payment method
- Fix a bug: do not display an untranslated string if a prepaid pack has no maximum validity
- Fix a bug: statistics not built for instances with plans created before v4.3.3
- Fix a bug: when requesting to send the sso migration code, the email was case-sensitive.
- Fix a bug: the adminsys email was case-sensitive.
- Fix a bug: when requesting to send the sso migration code, the email was case-sensitive
- Fix a bug: the adminsys email was case-sensitive
- Fix a bug: members are unable to buy prepaid-packs by wallet
- [TODO DEPLOY] `rails fablab:maintenance:regenerate_statistics[2020,04]`
# v5.3.1 2022 January 17

View File

@ -0,0 +1,95 @@
import { Invoice } from '../../../models/invoice';
import { PaymentSchedule } from '../../../models/payment-schedule';
import { ShoppingCart } from '../../../models/payment';
import { User } from '../../../models/user';
import React, { useEffect, useState } from 'react';
import WalletAPI from '../../../api/wallet';
import { Wallet } from '../../../models/wallet';
import WalletLib from '../../../lib/wallet';
import UserLib from '../../../lib/user';
import { LocalPaymentModal } from '../local-payment/local-payment-modal';
import { CardPaymentModal } from '../card-payment-modal';
import PriceAPI from '../../../api/price';
import { ComputePriceResult } from '../../../models/price';
interface PaymentModalProps {
isOpen: boolean,
toggleModal: () => void,
afterSuccess: (result: Invoice|PaymentSchedule) => void,
onError: (message: string) => void,
cart: ShoppingCart,
updateCart: (cart: ShoppingCart) => void,
operator: User,
schedule?: PaymentSchedule,
customer: User
}
/**
* This component is responsible for rendering the payment modal.
*/
export const PaymentModal: React.FC<PaymentModalProps> = ({ isOpen, toggleModal, afterSuccess, onError, cart, updateCart, operator, schedule, customer }) => {
// the user's wallet
const [wallet, setWallet] = useState<Wallet>(null);
// the price of the cart
const [price, setPrice] = useState<ComputePriceResult>(null);
// the remaining price to pay, after the wallet was changed
const [remainingPrice, setRemainingPrice] = useState<number>(null);
// refresh the wallet when the customer changes
useEffect(() => {
WalletAPI.getByUser(customer.id).then(wallet => {
setWallet(wallet);
});
}, [customer]);
// refresh the price when the cart changes
useEffect(() => {
PriceAPI.compute(cart).then(price => {
setPrice(price);
});
}, [cart]);
// refresh the remaining price when the cart price was computed and the wallet was retrieved
useEffect(() => {
if (price && wallet) {
setRemainingPrice(new WalletLib(wallet).computeRemainingPrice(price?.price));
}
}, [price, wallet]);
/**
* Check the conditions for the local payment
*/
const isLocalPayment = (): boolean => {
return (new UserLib(operator).isPrivileged(customer) || remainingPrice === 0);
};
// do not render the modal until the real remaining price is computed
if (remainingPrice === null) return null;
if (isLocalPayment()) {
return (
<LocalPaymentModal isOpen={isOpen}
toggleModal={toggleModal}
afterSuccess={afterSuccess}
onError={onError}
cart={cart}
updateCart={updateCart}
currentUser={operator}
customer={customer}
schedule={schedule}
/>
);
} else {
return (
<CardPaymentModal isOpen={isOpen}
toggleModal={toggleModal}
afterSuccess={afterSuccess}
onError={onError}
cart={cart}
currentUser={operator}
customer={customer}
schedule={schedule}
/>
);
}
};

View File

@ -9,10 +9,8 @@ import { FabButton } from '../base/fab-button';
import PriceAPI from '../../api/price';
import { Price } from '../../models/price';
import { PaymentMethod, ShoppingCart } from '../../models/payment';
import { CardPaymentModal } from '../payment/card-payment-modal';
import UserLib from '../../lib/user';
import { LocalPaymentModal } from '../payment/local-payment/local-payment-modal';
import FormatLib from '../../lib/format';
import { PaymentModal } from '../payment/stripe/payment-modal';
type PackableItem = Machine;
@ -38,7 +36,6 @@ export const ProposePacksModal: React.FC<ProposePacksModalProps> = ({ isOpen, to
const [packs, setPacks] = useState<Array<PrepaidPack>>(null);
const [cart, setCart] = useState<ShoppingCart>(null);
const [paymentModal, setPaymentModal] = useState<boolean>(false);
const [localPaymentModal, setLocalPaymentModal] = useState<boolean>(false);
useEffect(() => {
PrepaidPackAPI.index({ priceable_id: item.id, priceable_type: itemType, group_id: customer.group_id, disabled: false })
@ -56,13 +53,6 @@ export const ProposePacksModal: React.FC<ProposePacksModalProps> = ({ isOpen, to
setPaymentModal(!paymentModal);
};
/**
* Open/closes the local payment modal (for admins and managers)
*/
const toggleLocalPaymentModal = (): void => {
setLocalPaymentModal(!localPaymentModal);
};
/**
* Convert the hourly-based price of the given prive, to a total price, based on the duration of the given pack
*/
@ -107,9 +97,6 @@ export const ProposePacksModal: React.FC<ProposePacksModalProps> = ({ isOpen, to
{ prepaid_pack: { id: pack.id } }
]
});
if (new UserLib(operator).isPrivileged(customer)) {
return toggleLocalPaymentModal();
}
togglePaymentModal();
};
};
@ -154,21 +141,14 @@ export const ProposePacksModal: React.FC<ProposePacksModalProps> = ({ isOpen, to
{packs?.map(p => renderPack(p))}
</div>
{cart && <div>
<CardPaymentModal isOpen={paymentModal}
<PaymentModal isOpen={paymentModal}
toggleModal={togglePaymentModal}
afterSuccess={handlePackBought}
onError={onError}
cart={cart}
currentUser={operator}
customer={customer} />
<LocalPaymentModal isOpen={localPaymentModal}
toggleModal={toggleLocalPaymentModal}
afterSuccess={handlePackBought}
onError={onError}
cart={cart}
updateCart={setCart}
currentUser={operator}
customer={customer} />
operator={operator}
customer={customer}
updateCart={setCart} />
</div>}
</FabModal>
);