From ff80216d9b433960d0d75511a0cd9bfa2b2852ca Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 8 Feb 2024 15:59:17 +0100 Subject: [PATCH] (feat) Allow the admin to update payment method only the overdue subscription item without cancel PayZen subscription --- CHANGELOG.md | 2 ++ app/controllers/api/payment_schedules_controller.rb | 7 ++++--- app/frontend/src/javascript/api/payment-schedule.ts | 4 ++-- .../payment-schedule-item-actions.tsx | 10 ++++++---- .../payment-schedule/payment-schedules-table.tsx | 3 ++- .../payment-schedule/update-payment-mean-modal.tsx | 12 +++++++----- app/services/payment_schedule_service.rb | 5 ++--- app/workers/payment_schedule_item_worker.rb | 4 ++-- config/locales/app.admin.en.yml | 2 +- 9 files changed, 28 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 500debb22..10fbead69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/app/controllers/api/payment_schedules_controller.rb b/app/controllers/api/payment_schedules_controller.rb index ae5169f70..1b32a88b4 100644 --- a/app/controllers/api/payment_schedules_controller.rb +++ b/app/controllers/api/payment_schedules_controller.rb @@ -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 diff --git a/app/frontend/src/javascript/api/payment-schedule.ts b/app/frontend/src/javascript/api/payment-schedule.ts index c5ce67cf3..3bcf6bf73 100644 --- a/app/frontend/src/javascript/api/payment-schedule.ts +++ b/app/frontend/src/javascript/api/payment-schedule.ts @@ -48,8 +48,8 @@ export default class PaymentScheduleAPI { return res?.data; } - static async update (paymentSchedule: PaymentSchedule): Promise { - const res:AxiosResponse = await apiClient.patch(`/api/payment_schedules/${paymentSchedule.id}`, paymentSchedule); + static async update (paymentScheduleId: number, paymentScheduleItemId: number, paymentMethod: string): Promise { + const res:AxiosResponse = await apiClient.patch(`/api/payment_schedules/${paymentScheduleId}`, { payment_method: paymentMethod, payment_schedule_item_id: paymentScheduleItemId }); return res?.data; } } diff --git a/app/frontend/src/javascript/components/payment-schedule/payment-schedule-item-actions.tsx b/app/frontend/src/javascript/components/payment-schedule/payment-schedule-item-actions.tsx index 7a7e8f307..5aeb111ab 100644 --- a/app/frontend/src/javascript/components/payment-schedule/payment-schedule-item-actions.tsx +++ b/app/frontend/src/javascript/components/payment-schedule/payment-schedule-item-actions.tsx @@ -169,10 +169,10 @@ export const PaymentScheduleItemActions: React.FC { 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 => { 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 + paymentSchedule={paymentSchedule} + paymentScheduleItemId={paymentScheduleItem.id} + /> ); diff --git a/app/frontend/src/javascript/components/payment-schedule/payment-schedules-table.tsx b/app/frontend/src/javascript/components/payment-schedule/payment-schedules-table.tsx index 8bfa2dbe6..f9b439930 100644 --- a/app/frontend/src/javascript/components/payment-schedule/payment-schedules-table.tsx +++ b/app/frontend/src/javascript/components/payment-schedule/payment-schedules-table.tsx @@ -104,7 +104,8 @@ const PaymentSchedulesTable: React.FC = ({ 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)})`; diff --git a/app/frontend/src/javascript/components/payment-schedule/update-payment-mean-modal.tsx b/app/frontend/src/javascript/components/payment-schedule/update-payment-mean-modal.tsx index ad5ecaa34..95589bd71 100644 --- a/app/frontend/src/javascript/components/payment-schedule/update-payment-mean-modal.tsx +++ b/app/frontend/src/javascript/components/payment-schedule/update-payment-mean-modal.tsx @@ -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 = ({ isOpen, toggleModal, onError, afterSuccess, paymentSchedule }) => { +export const UpdatePaymentMeanModal: React.FC = ({ isOpen, toggleModal, onError, afterSuccess, paymentSchedule, paymentScheduleItemId }) => { const { t } = useTranslation('admin'); const [paymentMean, setPaymentMean] = React.useState(); @@ -42,10 +43,11 @@ export const UpdatePaymentMeanModal: React.FC = ({ * 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); diff --git a/app/services/payment_schedule_service.rb b/app/services/payment_schedule_service.rb index ff42945f5..a30dde574 100644 --- a/app/services/payment_schedule_service.rb +++ b/app/services/payment_schedule_service.rb @@ -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 diff --git a/app/workers/payment_schedule_item_worker.rb b/app/workers/payment_schedule_item_worker.rb index 10c5eceaa..3c3c393d2 100644 --- a/app/workers/payment_schedule_item_worker.rb +++ b/app/workers/payment_schedule_item_worker.rb @@ -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') diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index 57b6c3470..3ad1ddc67 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -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"