1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-28 09:24:24 +01:00

(feat) Allow the admin to update payment method only the overdue subscription item without cancel PayZen subscription

This commit is contained in:
Du Peng 2024-02-08 15:59:17 +01:00
parent 34e9a0cc97
commit ff80216d9b
9 changed files with 28 additions and 21 deletions

View File

@ -2,6 +2,8 @@
## Next release
- improvement: Allow the admin to update payment method only the overdue subscription item without cancel PayZen subscription
## v6.3.11 2024 February 2
- Fix a bug: if there is a reservation with a deleted user, it is not possible to delete the event

View File

@ -89,10 +89,11 @@ class API::PaymentSchedulesController < API::APIController
def update
authorize PaymentSchedule
if PaymentScheduleService.new.update_payment_mean(@payment_schedule, update_params)
payment_schedule_item = PaymentScheduleItem.find(update_params[:payment_schedule_item_id])
if PaymentScheduleService.new.update_payment_mean(payment_schedule_item, update_params[:payment_method])
render :show, status: :ok, location: @payment_schedule
else
render json: @payment_schedule.errors, status: :unprocessable_entity
render json: payment_schedule_item.errors, status: :unprocessable_entity
end
end
@ -107,6 +108,6 @@ class API::PaymentSchedulesController < API::APIController
end
def update_params
params.require(:payment_schedule).permit(:payment_method)
params.permit(:payment_method, :payment_schedule_item_id)
end
end

View File

@ -48,8 +48,8 @@ export default class PaymentScheduleAPI {
return res?.data;
}
static async update (paymentSchedule: PaymentSchedule): Promise<PaymentSchedule> {
const res:AxiosResponse<PaymentSchedule> = await apiClient.patch(`/api/payment_schedules/${paymentSchedule.id}`, paymentSchedule);
static async update (paymentScheduleId: number, paymentScheduleItemId: number, paymentMethod: string): Promise<PaymentSchedule> {
const res:AxiosResponse<PaymentSchedule> = await apiClient.patch(`/api/payment_schedules/${paymentScheduleId}`, { payment_method: paymentMethod, payment_schedule_item_id: paymentScheduleItemId });
return res?.data;
}
}

View File

@ -169,10 +169,10 @@ export const PaymentScheduleItemActions: React.FC<PaymentScheduleItemActionsProp
*/
const pendingActions = (): ReactElement => {
if (isPrivileged()) {
if (paymentSchedule.payment_method === PaymentMethod.Transfer) {
if (paymentSchedule.payment_method === PaymentMethod.Transfer || paymentScheduleItem.payment_method === PaymentMethod.Transfer) {
return confirmTransferButton();
}
if (paymentSchedule.payment_method === PaymentMethod.Check) {
if (paymentSchedule.payment_method === PaymentMethod.Check || paymentScheduleItem.payment_method === PaymentMethod.Check) {
return confirmCheckButton();
}
} else {
@ -202,7 +202,7 @@ export const PaymentScheduleItemActions: React.FC<PaymentScheduleItemActionsProp
*/
const newActions = (): Array<ReactElement> => {
const buttons = [];
if (paymentSchedule.payment_method === PaymentMethod.Card) {
if (paymentSchedule.payment_method === PaymentMethod.Card && !paymentScheduleItem.payment_method) {
buttons.push(updateCardButton());
}
if (isPrivileged()) {
@ -400,7 +400,9 @@ export const PaymentScheduleItemActions: React.FC<PaymentScheduleItemActionsProp
toggleModal={toggleUpdatePaymentMeanModal}
onError={onError}
afterSuccess={onPaymentMeanUpdateSuccess}
paymentSchedule={paymentSchedule} />
paymentSchedule={paymentSchedule}
paymentScheduleItemId={paymentScheduleItem.id}
/>
</div>
</span>
);

View File

@ -104,7 +104,8 @@ const PaymentSchedulesTable: React.FC<PaymentSchedulesTableProps> = ({ paymentSc
* Return the human-readable string for the status of the provided deadline.
*/
const formatState = (item: PaymentScheduleItem, schedule: PaymentSchedule): JSX.Element => {
let res = t(`app.shared.payment_schedules_table.state_${item.state}${item.state === 'pending' ? '_' + schedule.payment_method : ''}`);
const paymentMethod = item.payment_method || schedule.payment_method;
let res = t(`app.shared.payment_schedules_table.state_${item.state}${item.state === 'pending' ? '_' + paymentMethod : ''}`);
if (item.state === 'paid') {
const key = `app.shared.payment_schedules_table.method_${item.payment_method}`;
res += ` (${t(key)})`;

View File

@ -12,12 +12,13 @@ interface UpdatePaymentMeanModalProps {
onError: (message: string) => void,
afterSuccess: () => void,
paymentSchedule: PaymentSchedule
paymentScheduleItemId: number,
}
/**
* Component to allow the member to change his payment mean for the given payment schedule (e.g. from card to transfer)
*/
export const UpdatePaymentMeanModal: React.FC<UpdatePaymentMeanModalProps> = ({ isOpen, toggleModal, onError, afterSuccess, paymentSchedule }) => {
export const UpdatePaymentMeanModal: React.FC<UpdatePaymentMeanModalProps> = ({ isOpen, toggleModal, onError, afterSuccess, paymentSchedule, paymentScheduleItemId }) => {
const { t } = useTranslation('admin');
const [paymentMean, setPaymentMean] = React.useState<PaymentMethod>();
@ -42,10 +43,11 @@ export const UpdatePaymentMeanModal: React.FC<UpdatePaymentMeanModalProps> = ({
* When the user clicks on the update button, update the default payment mean for the given payment schedule
*/
const handlePaymentMeanUpdate = (): void => {
PaymentScheduleAPI.update({
id: paymentSchedule.id,
payment_method: paymentMean
}).then(() => {
PaymentScheduleAPI.update(
paymentSchedule.id,
paymentScheduleItemId,
paymentMean
).then(() => {
afterSuccess();
}).catch(error => {
onError(error.message);

View File

@ -177,9 +177,8 @@ class PaymentScheduleService
##
# Update the payment mean associated with the given PaymentSchedule and reset the erroneous items
##
def update_payment_mean(payment_schedule, payment_mean)
PaymentGatewayService.new.cancel_subscription(payment_schedule)
payment_schedule.update(payment_mean) && reset_erroneous_payment_schedule_items(payment_schedule)
def update_payment_mean(payment_schedule_item, payment_method)
payment_schedule_item.update(payment_method: payment_method, state: payment_schedule_item.due_date < Time.current ? 'pending' : 'new')
end
private

View File

@ -19,12 +19,12 @@ class PaymentScheduleItemWorker
# @param psi [PaymentScheduleItem]
def check_item(psi)
# the following depends on the payment method (card/check)
if psi.payment_schedule.payment_method == 'card'
if psi.payment_schedule.payment_method == 'card' && psi.payment_method.nil?
### Cards
PaymentGatewayService.new.process_payment_schedule_item(psi)
elsif psi.state == 'new'
### Check/Bank transfer (only new deadlines, to prevent spamming)
NotificationCenter.call type: "notify_admin_payment_schedule_#{psi.payment_schedule.payment_method}_deadline",
NotificationCenter.call type: "notify_admin_payment_schedule_#{psi.payment_method || psi.payment_schedule.payment_method}_deadline",
receiver: User.admins_and_managers,
attached_object: psi
psi.update(state: 'pending')

View File

@ -1147,7 +1147,7 @@ en:
date: "Date"
update_payment_mean_modal:
title: "Update the payment mean"
update_info: "Please specify below the new payment mean for this payment schedule to continue."
update_info: "Please specify below the payment method to update this payment schedule."
select_payment_mean: "Select a new payment mean"
method_Transfer: "By bank transfer"
method_Check: "By check"