mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-30 19:52:20 +01:00
Ability to select "bank transfer" as the payment mean for a payment schedule
This commit is contained in:
parent
d7ccbdbb52
commit
9922812111
@ -3,6 +3,7 @@
|
|||||||
- Ability to cancel a payement schedule from the interface
|
- Ability to cancel a payement schedule from the interface
|
||||||
- Ability to create slots in the past
|
- Ability to create slots in the past
|
||||||
- Ability to disable public account creation
|
- Ability to disable public account creation
|
||||||
|
- Ability to select "bank transfer" as the payment mean for a payment schedule
|
||||||
- Updated caniuse db
|
- Updated caniuse db
|
||||||
- Optimized the load time of the payment schedules list
|
- Optimized the load time of the payment schedules list
|
||||||
- Fix a bug: do not load Stripe if no keys were defined
|
- Fix a bug: do not load Stripe if no keys were defined
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
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[show_item cash_check refresh_item pay_item]
|
before_action :set_payment_schedule_item, only: %i[show_item cash_check confirm_transfer refresh_item pay_item]
|
||||||
|
|
||||||
# retrieve all payment schedules for the current user, paginated
|
# retrieve all payment schedules for the current user, paginated
|
||||||
def index
|
def index
|
||||||
@ -46,6 +46,15 @@ class API::PaymentSchedulesController < API::ApiController
|
|||||||
render json: attrs, status: :ok
|
render json: attrs, status: :ok
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def confirm_transfer
|
||||||
|
authorize @payment_schedule_item.payment_schedule
|
||||||
|
PaymentScheduleService.new.generate_invoice(@payment_schedule_item, payment_method: 'transfer')
|
||||||
|
attrs = { state: 'paid', payment_method: 'transfer' }
|
||||||
|
@payment_schedule_item.update_attributes(attrs)
|
||||||
|
|
||||||
|
render json: attrs, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
def refresh_item
|
def refresh_item
|
||||||
authorize @payment_schedule_item.payment_schedule
|
authorize @payment_schedule_item.payment_schedule
|
||||||
PaymentScheduleItemWorker.new.perform(@payment_schedule_item.id)
|
PaymentScheduleItemWorker.new.perform(@payment_schedule_item.id)
|
||||||
|
@ -23,6 +23,11 @@ export default class PaymentScheduleAPI {
|
|||||||
return res?.data;
|
return res?.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async confirmTransfer (paymentScheduleItemId: number): Promise<CashCheckResponse> {
|
||||||
|
const res: AxiosResponse = await apiClient.post(`/api/payment_schedules/items/${paymentScheduleItemId}/confirm_transfer`);
|
||||||
|
return res?.data;
|
||||||
|
}
|
||||||
|
|
||||||
static async getItem (paymentScheduleItemId: number): Promise<PaymentScheduleItem> {
|
static async getItem (paymentScheduleItemId: number): Promise<PaymentScheduleItem> {
|
||||||
const res: AxiosResponse = await apiClient.get(`/api/payment_schedules/items/${paymentScheduleItemId}`);
|
const res: AxiosResponse = await apiClient.get(`/api/payment_schedules/items/${paymentScheduleItemId}`);
|
||||||
return res?.data;
|
return res?.data;
|
||||||
|
@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
|
|
||||||
interface HtmlTranslateProps {
|
interface HtmlTranslateProps {
|
||||||
trKey: string,
|
trKey: string,
|
||||||
options?: Record<string, string>
|
options?: Record<string, string|number>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,6 +31,8 @@ const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({
|
|||||||
const [showExpanded, setShowExpanded] = useState<Map<number, boolean>>(new Map());
|
const [showExpanded, setShowExpanded] = useState<Map<number, boolean>>(new Map());
|
||||||
// is open, the modal dialog to confirm the cashing of a check?
|
// is open, the modal dialog to confirm the cashing of a check?
|
||||||
const [showConfirmCashing, setShowConfirmCashing] = useState<boolean>(false);
|
const [showConfirmCashing, setShowConfirmCashing] = useState<boolean>(false);
|
||||||
|
// is open, the modal dialog to confirm a back transfer?
|
||||||
|
const [showConfirmTransfer, setShowConfirmTransfer] = useState<boolean>(false);
|
||||||
// is open, the modal dialog the resolve a pending card payment?
|
// is open, the modal dialog the resolve a pending card payment?
|
||||||
const [showResolveAction, setShowResolveAction] = useState<boolean>(false);
|
const [showResolveAction, setShowResolveAction] = useState<boolean>(false);
|
||||||
// the user cannot confirm the action modal (3D secure), unless he has resolved the pending action
|
// the user cannot confirm the action modal (3D secure), unless he has resolved the pending action
|
||||||
@ -130,8 +132,8 @@ const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({
|
|||||||
/**
|
/**
|
||||||
* Return the human-readable string for the status of the provided deadline.
|
* Return the human-readable string for the status of the provided deadline.
|
||||||
*/
|
*/
|
||||||
const formatState = (item: PaymentScheduleItem): JSX.Element => {
|
const formatState = (item: PaymentScheduleItem, schedule: PaymentSchedule): JSX.Element => {
|
||||||
let res = t(`app.shared.schedules_table.state_${item.state}`);
|
let res = t(`app.shared.schedules_table.state_${item.state}${item.state === 'pending' ? '_' + schedule.payment_method : ''}`);
|
||||||
if (item.state === PaymentScheduleItemState.Paid) {
|
if (item.state === PaymentScheduleItemState.Paid) {
|
||||||
const key = `app.shared.schedules_table.method_${item.payment_method}`;
|
const key = `app.shared.schedules_table.method_${item.payment_method}`;
|
||||||
res += ` (${t(key)})`;
|
res += ` (${t(key)})`;
|
||||||
@ -155,12 +157,21 @@ const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({
|
|||||||
return downloadButton(TargetType.Invoice, item.invoice_id);
|
return downloadButton(TargetType.Invoice, item.invoice_id);
|
||||||
case PaymentScheduleItemState.Pending:
|
case PaymentScheduleItemState.Pending:
|
||||||
if (isPrivileged()) {
|
if (isPrivileged()) {
|
||||||
|
if (schedule.payment_method === 'transfer') {
|
||||||
return (
|
return (
|
||||||
<FabButton onClick={handleConfirmCheckPayment(item)}
|
<FabButton onClick={handleConfirmTransferPayment(item)}
|
||||||
icon={<i className="fas fa-money-check" />}>
|
icon={<i className="fas fa-university"/>}>
|
||||||
{t('app.shared.schedules_table.confirm_payment')}
|
{t('app.shared.schedules_table.confirm_payment')}
|
||||||
</FabButton>
|
</FabButton>
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<FabButton onClick={handleConfirmCheckPayment(item)}
|
||||||
|
icon={<i className="fas fa-money-check"/>}>
|
||||||
|
{t('app.shared.schedules_table.confirm_payment')}
|
||||||
|
</FabButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return <span>{t('app.shared.schedules_table.please_ask_reception')}</span>;
|
return <span>{t('app.shared.schedules_table.please_ask_reception')}</span>;
|
||||||
}
|
}
|
||||||
@ -216,6 +227,15 @@ const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback triggered when the user's clicks on the "confirm transfer" button: show a confirmation modal
|
||||||
|
*/
|
||||||
|
const handleConfirmTransferPayment = (item: PaymentScheduleItem): ReactEventHandler => {
|
||||||
|
return (): void => {
|
||||||
|
setTempDeadline(item);
|
||||||
|
toggleConfirmTransferModal();
|
||||||
|
};
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* After the user has confirmed that he wants to cash the check, update the API, refresh the list and close the modal.
|
* After the user has confirmed that he wants to cash the check, update the API, refresh the list and close the modal.
|
||||||
*/
|
*/
|
||||||
@ -228,6 +248,18 @@ const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After the user has confirmed that he validates the tranfer, update the API, refresh the list and close the modal.
|
||||||
|
*/
|
||||||
|
const onTransferConfirmed = (): void => {
|
||||||
|
PaymentScheduleAPI.confirmTransfer(tempDeadline.id).then((res) => {
|
||||||
|
if (res.state === PaymentScheduleItemState.Paid) {
|
||||||
|
refreshSchedulesTable();
|
||||||
|
toggleConfirmTransferModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh all payment schedules in the table
|
* Refresh all payment schedules in the table
|
||||||
*/
|
*/
|
||||||
@ -242,6 +274,13 @@ const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({
|
|||||||
setShowConfirmCashing(!showConfirmCashing);
|
setShowConfirmCashing(!showConfirmCashing);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show/hide the modal dialog that enable to confirm the bank transfer for a given deadline.
|
||||||
|
*/
|
||||||
|
const toggleConfirmTransferModal = (): void => {
|
||||||
|
setShowConfirmTransfer(!showConfirmTransfer);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show/hide the modal dialog that trigger the card "action".
|
* Show/hide the modal dialog that trigger the card "action".
|
||||||
*/
|
*/
|
||||||
@ -392,7 +431,7 @@ const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({
|
|||||||
{_.orderBy(p.items, 'due_date').map(item => <tr key={item.id}>
|
{_.orderBy(p.items, 'due_date').map(item => <tr key={item.id}>
|
||||||
<td>{FormatLib.date(item.due_date)}</td>
|
<td>{FormatLib.date(item.due_date)}</td>
|
||||||
<td>{FormatLib.price(item.amount)}</td>
|
<td>{FormatLib.price(item.amount)}</td>
|
||||||
<td>{formatState(item)}</td>
|
<td>{formatState(item, p)}</td>
|
||||||
<td>{itemButtons(item, p)}</td>
|
<td>{itemButtons(item, p)}</td>
|
||||||
</tr>)}
|
</tr>)}
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -421,6 +460,20 @@ const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({
|
|||||||
})}
|
})}
|
||||||
</span>}
|
</span>}
|
||||||
</FabModal>
|
</FabModal>
|
||||||
|
{/* Confirm the bank transfer for the current deadline */}
|
||||||
|
<FabModal title={t('app.shared.schedules_table.confirm_bank_transfer')}
|
||||||
|
isOpen={showConfirmTransfer}
|
||||||
|
toggleModal={toggleConfirmTransferModal}
|
||||||
|
onConfirm={onTransferConfirmed}
|
||||||
|
closeButton={true}
|
||||||
|
confirmButton={t('app.shared.schedules_table.confirm_button')}>
|
||||||
|
{tempDeadline && <span>
|
||||||
|
{t('app.shared.schedules_table.confirm_bank_transfer_body', {
|
||||||
|
AMOUNT: FormatLib.price(tempDeadline.amount),
|
||||||
|
DATE: FormatLib.date(tempDeadline.due_date)
|
||||||
|
})}
|
||||||
|
</span>}
|
||||||
|
</FabModal>
|
||||||
{/* Cancel the subscription */}
|
{/* Cancel the subscription */}
|
||||||
<FabModal title={t('app.shared.schedules_table.cancel_subscription')}
|
<FabModal title={t('app.shared.schedules_table.cancel_subscription')}
|
||||||
isOpen={showCancelSubscription}
|
isOpen={showCancelSubscription}
|
||||||
|
@ -8,9 +8,9 @@ import SettingAPI from '../../../api/setting';
|
|||||||
import { SettingName } from '../../../models/setting';
|
import { SettingName } from '../../../models/setting';
|
||||||
import { PaymentModal } from '../payment-modal';
|
import { PaymentModal } from '../payment-modal';
|
||||||
import { PaymentSchedule } from '../../../models/payment-schedule';
|
import { PaymentSchedule } from '../../../models/payment-schedule';
|
||||||
import { PaymentMethod } from '../../../models/payment';
|
import { HtmlTranslate } from '../../base/html-translate';
|
||||||
|
|
||||||
const ALL_SCHEDULE_METHODS = ['card', 'check'] as const;
|
const ALL_SCHEDULE_METHODS = ['card', 'check', 'transfer'] as const;
|
||||||
type scheduleMethod = typeof ALL_SCHEDULE_METHODS[number];
|
type scheduleMethod = typeof ALL_SCHEDULE_METHODS[number];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,11 +31,7 @@ export const LocalPaymentForm: React.FC<GatewayFormProps> = ({ onSubmit, onSucce
|
|||||||
const [onlinePaymentModal, setOnlinePaymentModal] = useState<boolean>(false);
|
const [onlinePaymentModal, setOnlinePaymentModal] = useState<boolean>(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cart.payment_method === PaymentMethod.Card) {
|
setMethod(cart.payment_method || 'check');
|
||||||
setMethod('card');
|
|
||||||
} else {
|
|
||||||
setMethod('check');
|
|
||||||
}
|
|
||||||
}, [cart]);
|
}, [cart]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,11 +61,7 @@ export const LocalPaymentForm: React.FC<GatewayFormProps> = ({ onSubmit, onSucce
|
|||||||
* Callback triggered when the user selects a payment method for the current payment schedule.
|
* Callback triggered when the user selects a payment method for the current payment schedule.
|
||||||
*/
|
*/
|
||||||
const handleUpdateMethod = (option: selectOption) => {
|
const handleUpdateMethod = (option: selectOption) => {
|
||||||
if (option.value === 'card') {
|
updateCart(Object.assign({}, cart, { payment_method: option.value }));
|
||||||
updateCart(Object.assign({}, cart, { payment_method: PaymentMethod.Card }));
|
|
||||||
} else {
|
|
||||||
updateCart(Object.assign({}, cart, { payment_method: PaymentMethod.Other }));
|
|
||||||
}
|
|
||||||
setMethod(option.value);
|
setMethod(option.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -140,6 +132,7 @@ export const LocalPaymentForm: React.FC<GatewayFormProps> = ({ onSubmit, onSucce
|
|||||||
value={methodToOption(method)} />
|
value={methodToOption(method)} />
|
||||||
{method === 'card' && <p>{t('app.admin.local_payment.card_collection_info')}</p>}
|
{method === 'card' && <p>{t('app.admin.local_payment.card_collection_info')}</p>}
|
||||||
{method === 'check' && <p>{t('app.admin.local_payment.check_collection_info', { DEADLINES: paymentSchedule.items.length })}</p>}
|
{method === 'check' && <p>{t('app.admin.local_payment.check_collection_info', { DEADLINES: paymentSchedule.items.length })}</p>}
|
||||||
|
{method === 'transfer' && <HtmlTranslate trKey="app.admin.local_payment.transfer_collection_info" options={{ DEADLINES: paymentSchedule.items.length }} />}
|
||||||
</div>
|
</div>
|
||||||
<div className="full-schedule">
|
<div className="full-schedule">
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -59,6 +59,7 @@ const UpdateCardModalComponent: React.FC<UpdateCardModalProps> = ({ isOpen, togg
|
|||||||
case 'PayZen':
|
case 'PayZen':
|
||||||
return renderPayZenModal();
|
return renderPayZenModal();
|
||||||
case '':
|
case '':
|
||||||
|
case undefined:
|
||||||
return <div/>;
|
return <div/>;
|
||||||
default:
|
default:
|
||||||
onError(t('app.shared.update_card_modal.unexpected_error'));
|
onError(t('app.shared.update_card_modal.unexpected_error'));
|
||||||
|
@ -26,7 +26,7 @@ export interface PaymentSchedule {
|
|||||||
id: number,
|
id: number,
|
||||||
total: number,
|
total: number,
|
||||||
reference: string,
|
reference: string,
|
||||||
payment_method: 'card' | '',
|
payment_method: 'card' | 'transfer' | '',
|
||||||
items: Array<PaymentScheduleItem>,
|
items: Array<PaymentScheduleItem>,
|
||||||
created_at: Date,
|
created_at: Date,
|
||||||
chained_footprint: boolean,
|
chained_footprint: boolean,
|
||||||
|
@ -18,7 +18,8 @@ export interface IntentConfirmation {
|
|||||||
|
|
||||||
export enum PaymentMethod {
|
export enum PaymentMethod {
|
||||||
Card = 'card',
|
Card = 'card',
|
||||||
Other = ''
|
Check = 'check',
|
||||||
|
Transfer = 'transfer'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CartItem = { reservation: Reservation }|
|
export type CartItem = { reservation: Reservation }|
|
||||||
|
@ -58,6 +58,7 @@ class NotificationType
|
|||||||
notify_admin_payment_schedule_failed
|
notify_admin_payment_schedule_failed
|
||||||
notify_member_payment_schedule_failed
|
notify_member_payment_schedule_failed
|
||||||
notify_admin_payment_schedule_check_deadline
|
notify_admin_payment_schedule_check_deadline
|
||||||
|
notify_admin_payment_schedule_transfer_deadline
|
||||||
]
|
]
|
||||||
# deprecated:
|
# deprecated:
|
||||||
# - notify_member_subscribed_plan_is_changed
|
# - notify_member_subscribed_plan_is_changed
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Check the access policies for API::PaymentSchedulesController
|
# Check the access policies for API::PaymentSchedulesController
|
||||||
class PaymentSchedulePolicy < ApplicationPolicy
|
class PaymentSchedulePolicy < ApplicationPolicy
|
||||||
%w[list? cash_check? cancel?].each do |action|
|
%w[list? cash_check? confirm_transfer? cancel?].each do |action|
|
||||||
define_method action do
|
define_method action do
|
||||||
user.admin? || user.manager?
|
user.admin? || user.manager?
|
||||||
end
|
end
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
json.title notification.notification_type
|
||||||
|
json.description t('.schedule_deadline', DATE: I18n.l(notification.attached_object.due_date.to_date),
|
||||||
|
REFERENCE: notification.attached_object.payment_schedule.reference)
|
@ -0,0 +1,10 @@
|
|||||||
|
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= t('.body.remember',
|
||||||
|
REFERENCE: @attached_object.payment_schedule.reference,
|
||||||
|
AMOUNT: number_to_currency(@attached_object.amount / 100.00),
|
||||||
|
DATE: I18n.l(@attached_object.due_date, format: :long)) %>
|
||||||
|
<%= t('.body.date') %>
|
||||||
|
</p>
|
||||||
|
<p><%= t('.body.confirm') %></p>
|
@ -22,8 +22,8 @@ class PaymentScheduleItemWorker
|
|||||||
### Cards
|
### Cards
|
||||||
PaymentGatewayService.new.process_payment_schedule_item(psi)
|
PaymentGatewayService.new.process_payment_schedule_item(psi)
|
||||||
elsif psi.state == 'new'
|
elsif psi.state == 'new'
|
||||||
### Check (only new deadlines, to prevent spamming)
|
### Check/Bank transfer (only new deadlines, to prevent spamming)
|
||||||
NotificationCenter.call type: 'notify_admin_payment_schedule_check_deadline',
|
NotificationCenter.call type: "notify_admin_payment_schedule_#{psi.payment_schedule.payment_method}_deadline",
|
||||||
receiver: User.admins_and_managers,
|
receiver: User.admins_and_managers,
|
||||||
attached_object: psi
|
attached_object: psi
|
||||||
psi.update_attributes(state: 'pending')
|
psi.update_attributes(state: 'pending')
|
||||||
|
@ -1451,8 +1451,10 @@ en:
|
|||||||
payment_method: "Payment method"
|
payment_method: "Payment method"
|
||||||
method_card: "Online by card"
|
method_card: "Online by card"
|
||||||
method_check: "By check"
|
method_check: "By check"
|
||||||
|
method_transfer: "By bank transfer"
|
||||||
card_collection_info: "By validating, you'll be prompted for the member's card number. This card will be automatically charged at the deadlines."
|
card_collection_info: "By validating, you'll be prompted for the member's card number. This card will be automatically charged at the deadlines."
|
||||||
check_collection_info: "By validating, you confirm that you have {DEADLINES} checks, allowing you to collect all the monthly payments."
|
check_collection_info: "By validating, you confirm that you have {DEADLINES} checks, allowing you to collect all the monthly payments."
|
||||||
|
transfer_collection_info: "<p>By validating, you confirm that you set up {DEADLINES} bank direct debits, allowing you to collect all the monthly payments.</p><p><strong>Please note:</strong> the bank transfers are not automatically handled by Fab-manager.</p>"
|
||||||
online_payment_disabled: "Online payment is not available. You cannot collect this payment schedule by online card."
|
online_payment_disabled: "Online payment is not available. You cannot collect this payment schedule by online card."
|
||||||
check_list_setting:
|
check_list_setting:
|
||||||
save: 'Save'
|
save: 'Save'
|
||||||
|
@ -487,7 +487,8 @@ en:
|
|||||||
state: "State"
|
state: "State"
|
||||||
download: "Download"
|
download: "Download"
|
||||||
state_new: "Not yet due"
|
state_new: "Not yet due"
|
||||||
state_pending: "Waiting for the cashing of the check"
|
state_pending_check: "Waiting for the cashing of the check"
|
||||||
|
state_pending_transfer: "Waiting for the tranfer confirmation"
|
||||||
state_requires_payment_method: "The credit card must be updated"
|
state_requires_payment_method: "The credit card must be updated"
|
||||||
state_requires_action: "Action required"
|
state_requires_action: "Action required"
|
||||||
state_paid: "Paid"
|
state_paid: "Paid"
|
||||||
@ -495,11 +496,14 @@ en:
|
|||||||
state_canceled: "Canceled"
|
state_canceled: "Canceled"
|
||||||
method_card: "by card"
|
method_card: "by card"
|
||||||
method_check: "by check"
|
method_check: "by check"
|
||||||
|
method_transfer: "by transfer"
|
||||||
confirm_payment: "Confirm payment"
|
confirm_payment: "Confirm payment"
|
||||||
solve: "Solve"
|
solve: "Solve"
|
||||||
update_card: "Update the card"
|
update_card: "Update the card"
|
||||||
confirm_check_cashing: "Confirm the cashing of the check"
|
confirm_check_cashing: "Confirm the cashing of the check"
|
||||||
confirm_check_cashing_body: "You must cash a check of {AMOUNT} for the deadline of {DATE}. By confirming the cashing of the check, an invoice will be generated for this due date."
|
confirm_check_cashing_body: "You must cash a check of {AMOUNT} for the deadline of {DATE}. By confirming the cashing of the check, an invoice will be generated for this due date."
|
||||||
|
confirm_bank_transfer: "Confirm the bank transfer"
|
||||||
|
confirm_bank_transfer_body: "You must confirm the receipt of {AMOUNT} for the deadline of {DATE}. By confirming the bank transfer, an invoice will be generated for this due date."
|
||||||
confirm_button: "Confirm"
|
confirm_button: "Confirm"
|
||||||
resolve_action: "Resolve the action"
|
resolve_action: "Resolve the action"
|
||||||
ok_button: "OK"
|
ok_button: "OK"
|
||||||
|
@ -126,7 +126,7 @@ en:
|
|||||||
deadline_date: "Payment date"
|
deadline_date: "Payment date"
|
||||||
deadline_amount: "Amount including tax"
|
deadline_amount: "Amount including tax"
|
||||||
total_amount: "Total amount"
|
total_amount: "Total amount"
|
||||||
settlement_by_METHOD: "Debits will be made by {METHOD, select, card{card} other{check}} for each deadlines."
|
settlement_by_METHOD: "Debits will be made by {METHOD, select, card{card} transfer{bank transfer} other{check}} for each deadlines."
|
||||||
settlement_by_wallet: "%{AMOUNT} will be debited from your wallet to settle the first deadline."
|
settlement_by_wallet: "%{AMOUNT} will be debited from your wallet to settle the first deadline."
|
||||||
# CVS accounting export (columns headers)
|
# CVS accounting export (columns headers)
|
||||||
accounting_export:
|
accounting_export:
|
||||||
@ -373,6 +373,8 @@ en:
|
|||||||
schedule_failed: "Failed card debit for the %{DATE} deadline, for your schedule %{REFERENCE}"
|
schedule_failed: "Failed card debit for the %{DATE} deadline, for your schedule %{REFERENCE}"
|
||||||
notify_admin_payment_schedule_check_deadline:
|
notify_admin_payment_schedule_check_deadline:
|
||||||
schedule_deadline: "You must cash the check for the %{DATE} deadline, for schedule %{REFERENCE}"
|
schedule_deadline: "You must cash the check for the %{DATE} deadline, for schedule %{REFERENCE}"
|
||||||
|
notify_admin_payment_schedule_transfer_deadline:
|
||||||
|
schedule_deadline: "You must confirm the bank direct debit for the %{DATE} deadline, for schedule %{REFERENCE}"
|
||||||
#statistics tools for admins
|
#statistics tools for admins
|
||||||
statistics:
|
statistics:
|
||||||
subscriptions: "Subscriptions"
|
subscriptions: "Subscriptions"
|
||||||
|
@ -315,5 +315,11 @@ en:
|
|||||||
remember: "In accordance with the %{REFERENCE} payment schedule, %{AMOUNT} was due to be debited on %{DATE}."
|
remember: "In accordance with the %{REFERENCE} payment schedule, %{AMOUNT} was due to be debited on %{DATE}."
|
||||||
date: "This is a reminder to cash the scheduled check as soon as possible."
|
date: "This is a reminder to cash the scheduled check as soon as possible."
|
||||||
confirm: "Do not forget to confirm the receipt in your payment schedule management interface, so that the corresponding invoice will be generated."
|
confirm: "Do not forget to confirm the receipt in your payment schedule management interface, so that the corresponding invoice will be generated."
|
||||||
|
notify_member_payment_schedule_transfer_deadline:
|
||||||
|
subject: "Payment deadline"
|
||||||
|
body:
|
||||||
|
remember: "In accordance with your %{REFERENCE} payment schedule, %{AMOUNT} was due to be debited on %{DATE}."
|
||||||
|
date: "This is a reminder to verify that the direct bank debit was successfull."
|
||||||
|
confirm: "Please confirm the receipt of funds in your payment schedule management interface, so that the corresponding invoice will be generated."
|
||||||
shared:
|
shared:
|
||||||
hello: "Hello %{user_name}"
|
hello: "Hello %{user_name}"
|
||||||
|
@ -125,6 +125,7 @@ Rails.application.routes.draw do
|
|||||||
get 'download', on: :member
|
get 'download', on: :member
|
||||||
get 'items/:id', action: 'show_item', on: :collection
|
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/confirm_transfer', action: 'confirm_transfer', 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
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user