mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-03-22 13:19:50 +01:00
Merge branch 'dev' for release 6.3.16
This commit is contained in:
commit
91a1dc12e2
@ -2,6 +2,14 @@
|
||||
|
||||
## Next release
|
||||
|
||||
## v6.3.16 2024 March 11
|
||||
|
||||
- Fix a bug: set settlement by cash by default for local payment mean
|
||||
- updates translations
|
||||
- #content_type_whitelist is instead by #content_type_allowlist
|
||||
- #extension_whitelist is instead by #extension_allowlist
|
||||
- [TODO DEPLOY] `rails fablab:setup:build_accounting_lines`
|
||||
|
||||
## v6.3.15 2024 February 29
|
||||
|
||||
- Fix a bug: unable to generate invoice for payment by check/transfer
|
||||
|
@ -13,8 +13,8 @@ import CheckoutAPI from '../../../api/checkout';
|
||||
import { SelectOption } from '../../../models/select';
|
||||
import { PaymentMethod } from '../../../models/payment';
|
||||
|
||||
const ALL_SCHEDULE_METHODS = ['card', 'check', 'transfer'] as const;
|
||||
type scheduleMethod = typeof ALL_SCHEDULE_METHODS[number];
|
||||
const ALL_PAYMENT_METHODS = ['card', 'check', 'transfer', 'cash'] as const;
|
||||
type paymentMethod = typeof ALL_PAYMENT_METHODS[number];
|
||||
|
||||
/**
|
||||
* A form component to ask for confirmation before cashing a payment directly at the FabLab's reception.
|
||||
@ -24,13 +24,13 @@ type scheduleMethod = typeof ALL_SCHEDULE_METHODS[number];
|
||||
export const LocalPaymentForm: React.FC<GatewayFormProps> = ({ onSubmit, onSuccess, onError, children, className, paymentSchedule, cart, updateCart, customer, operator, formId, order }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
const [method, setMethod] = useState<scheduleMethod>('check');
|
||||
const [method, setMethod] = useState<paymentMethod>('cash');
|
||||
const [onlinePaymentModal, setOnlinePaymentModal] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMethod(cart.payment_method || 'check');
|
||||
setMethod(cart.payment_method || 'cash');
|
||||
if (cart.payment_method === '') {
|
||||
cart.payment_method = PaymentMethod.Check;
|
||||
cart.payment_method = PaymentMethod.Cash;
|
||||
}
|
||||
}, [cart]);
|
||||
|
||||
@ -44,15 +44,15 @@ export const LocalPaymentForm: React.FC<GatewayFormProps> = ({ onSubmit, onSucce
|
||||
/**
|
||||
* Convert all payement methods for schedules to the react-select format
|
||||
*/
|
||||
const buildMethodOptions = (): Array<SelectOption<scheduleMethod>> => {
|
||||
return ALL_SCHEDULE_METHODS.map(i => methodToOption(i));
|
||||
const buildMethodOptions = (): Array<SelectOption<paymentMethod>> => {
|
||||
return ALL_PAYMENT_METHODS.filter(p => p !== 'cash').map(i => methodToOption(i));
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert the given payment-method to the react-select format
|
||||
*/
|
||||
const methodToOption = (value: scheduleMethod): SelectOption<scheduleMethod> => {
|
||||
if (!value) return { value, label: '' };
|
||||
const methodToOption = (value: paymentMethod): SelectOption<paymentMethod> => {
|
||||
if (!value || value === 'cash') return { value, label: '' };
|
||||
|
||||
return { value, label: t(`app.admin.local_payment_form.method_${value}`) };
|
||||
};
|
||||
@ -60,7 +60,7 @@ export const LocalPaymentForm: React.FC<GatewayFormProps> = ({ onSubmit, onSucce
|
||||
/**
|
||||
* Callback triggered when the user selects a payment method for the current payment schedule.
|
||||
*/
|
||||
const handleUpdateMethod = (option: SelectOption<scheduleMethod>) => {
|
||||
const handleUpdateMethod = (option: SelectOption<paymentMethod>) => {
|
||||
updateCart(Object.assign({}, cart, { payment_method: option.value }));
|
||||
setMethod(option.value);
|
||||
};
|
||||
@ -69,6 +69,10 @@ export const LocalPaymentForm: React.FC<GatewayFormProps> = ({ onSubmit, onSucce
|
||||
* Handle the submission of the form. It will process the local payment.
|
||||
*/
|
||||
const handleSubmit = async (event: FormEvent): Promise<void> => {
|
||||
if (paymentSchedule && !ALL_PAYMENT_METHODS.filter(p => p !== 'cash').includes(method)) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
onSubmit();
|
||||
|
||||
|
@ -19,6 +19,7 @@ export enum PaymentMethod {
|
||||
Card = 'card',
|
||||
Check = 'check',
|
||||
Transfer = 'transfer',
|
||||
Cash = 'cash',
|
||||
Other = ''
|
||||
}
|
||||
|
||||
|
@ -165,8 +165,6 @@ class Invoice < PaymentDocument
|
||||
|
||||
if paid_by_card?
|
||||
res.push(means: :card, amount: amount_paid)
|
||||
elsif paid_by_wallet?
|
||||
res.push(means: :wallet, amount: amount_paid)
|
||||
elsif paid_by_transfer?
|
||||
res.push(means: :transfer, amount: amount_paid)
|
||||
elsif paid_by_check?
|
||||
|
@ -48,11 +48,11 @@ class CustomAssetsUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[pdf png jpeg jpg ico]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
[%r{image/}, 'application/pdf']
|
||||
end
|
||||
|
||||
|
@ -41,11 +41,11 @@ class EventFileUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[pdf]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
%w[application/pdf]
|
||||
end
|
||||
|
||||
|
@ -59,11 +59,11 @@ class EventImageUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[jpg jpeg gif png]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
[%r{image/}]
|
||||
end
|
||||
|
||||
|
@ -22,11 +22,11 @@ class ImportUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[csv]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
%w[text/csv]
|
||||
end
|
||||
|
||||
|
@ -41,11 +41,11 @@ class MachineFileUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[pdf]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
%w[application/pdf]
|
||||
end
|
||||
|
||||
|
@ -51,11 +51,11 @@ class MachineImageUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[jpg jpeg gif png]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
[%r{image/}]
|
||||
end
|
||||
|
||||
|
@ -41,11 +41,11 @@ class PlanFileUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[pdf png jpeg jpg]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
[%r{image/}, 'application/pdf']
|
||||
end
|
||||
|
||||
|
@ -46,11 +46,11 @@ class ProductFileUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[pdf]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
['application/pdf']
|
||||
end
|
||||
|
||||
|
@ -39,11 +39,11 @@ class ProductImageUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[jpg jpeg gif png webp]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
[%r{image/}]
|
||||
end
|
||||
|
||||
|
@ -23,11 +23,11 @@ class ProjectCaoUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
Setting.get('allowed_cad_extensions').split(' ')
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
Setting.get('allowed_cad_mime_types').split(' ')
|
||||
end
|
||||
end
|
||||
|
@ -29,11 +29,11 @@ class ProjectImageUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[jpg jpeg gif png]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
[%r{image/}]
|
||||
end
|
||||
|
||||
|
@ -41,11 +41,11 @@ class SpaceFileUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[pdf]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
%w[application/pdf]
|
||||
end
|
||||
|
||||
|
@ -51,11 +51,11 @@ class SpaceImageUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[jpg jpeg gif png]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
[%r{image/}]
|
||||
end
|
||||
|
||||
|
@ -47,11 +47,11 @@ class SupportingDocumentFileUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[pdf png jpeg jpg]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
[%r{image/}, 'application/pdf']
|
||||
end
|
||||
|
||||
|
@ -51,11 +51,11 @@ class TrainingImageUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[jpg jpeg gif png]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
[%r{image/}]
|
||||
end
|
||||
|
||||
|
@ -55,11 +55,11 @@ class UserAvatarUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[jpg jpeg gif png]
|
||||
end
|
||||
|
||||
def content_type_whitelist
|
||||
def content_type_allowlist
|
||||
%w[image/jpeg image/gif image/png]
|
||||
end
|
||||
|
||||
|
@ -155,7 +155,7 @@ de:
|
||||
discover_members: "Mitglieder entdecken"
|
||||
#next events summary on the home page
|
||||
fablab_s_next_events: "Next events"
|
||||
every_events: "Alle Veranstaltungen"
|
||||
every_events: "All events"
|
||||
event_card:
|
||||
on_the_date: "Am {DATE}"
|
||||
from_date_to_date: "Von {START} bis {END}"
|
||||
|
@ -155,7 +155,7 @@ en:
|
||||
discover_members: "Discover members"
|
||||
#next events summary on the home page
|
||||
fablab_s_next_events: "Next events"
|
||||
every_events: "Every events"
|
||||
every_events: "All events"
|
||||
event_card:
|
||||
on_the_date: "On the {DATE}"
|
||||
from_date_to_date: "From {START} to {END}"
|
||||
|
@ -155,7 +155,7 @@ es-MX:
|
||||
discover_members: "Descubrir miembros"
|
||||
#next events summary on the home page
|
||||
fablab_s_next_events: "Próximos eventos"
|
||||
every_events: "Todos los eventos"
|
||||
every_events: "All events"
|
||||
event_card:
|
||||
on_the_date: "El {DATE}"
|
||||
from_date_to_date: "Desde {START} hasta {END}"
|
||||
|
@ -155,7 +155,7 @@ es:
|
||||
discover_members: "Descubrir miembros"
|
||||
#next events summary on the home page
|
||||
fablab_s_next_events: "Próximos eventos"
|
||||
every_events: "Todos los eventos"
|
||||
every_events: "All events"
|
||||
event_card:
|
||||
on_the_date: "El {DATE}"
|
||||
from_date_to_date: "Desde {START} hasta {END}"
|
||||
|
@ -155,7 +155,7 @@ it:
|
||||
discover_members: "Cerca i membri"
|
||||
#next events summary on the home page
|
||||
fablab_s_next_events: "Prossimi eventi"
|
||||
every_events: "Tutti gli eventi"
|
||||
every_events: "All events"
|
||||
event_card:
|
||||
on_the_date: "Il {DATE}"
|
||||
from_date_to_date: "Da {START} a {END}"
|
||||
|
@ -155,7 +155,7 @@
|
||||
discover_members: "Oppdag medlemmer"
|
||||
#next events summary on the home page
|
||||
fablab_s_next_events: "Next events"
|
||||
every_events: "Alle arrangementer"
|
||||
every_events: "All events"
|
||||
event_card:
|
||||
on_the_date: "På {DATE}"
|
||||
from_date_to_date: "Fra {START} til {END}"
|
||||
|
@ -155,7 +155,7 @@ pt:
|
||||
discover_members: "Ver membros"
|
||||
#next events summary on the home page
|
||||
fablab_s_next_events: "Próximos eventos"
|
||||
every_events: "Todos Eventos"
|
||||
every_events: "All events"
|
||||
event_card:
|
||||
on_the_date: "Em {DATE}"
|
||||
from_date_to_date: "De {START} até {END}"
|
||||
|
@ -155,7 +155,7 @@ sv:
|
||||
discover_members: "Upptäck medlemmar"
|
||||
#next events summary on the home page
|
||||
fablab_s_next_events: "Nästa evenemang"
|
||||
every_events: "Alla evenemang"
|
||||
every_events: "All events"
|
||||
event_card:
|
||||
on_the_date: "Den {DATE}"
|
||||
from_date_to_date: "Från {START} till {END}"
|
||||
|
@ -155,7 +155,7 @@ zu:
|
||||
discover_members: "crwdns28036:0crwdne28036:0"
|
||||
#next events summary on the home page
|
||||
fablab_s_next_events: "crwdns36235:0crwdne36235:0"
|
||||
every_events: "crwdns28040:0crwdne28040:0"
|
||||
every_events: "crwdns38182:0crwdne38182:0"
|
||||
event_card:
|
||||
on_the_date: "crwdns28042:0{DATE}crwdne28042:0"
|
||||
from_date_to_date: "crwdns28044:0{START}crwdnd28044:0{END}crwdne28044:0"
|
||||
|
@ -127,7 +127,7 @@ de:
|
||||
no_refund: "Keine Rückerstattung"
|
||||
settlement_by_debit_card: "Abrechnung per Debitkarte"
|
||||
settlement_by_transfer: "Settlement by transfer"
|
||||
settlement_by_check: "Settlement by check"
|
||||
settlement_by_check: "Settlement done at the reception"
|
||||
settlement_done_at_the_reception: "Abrechnung an der Rezeption durchgeführt"
|
||||
settlement_by_wallet: "Abrechnung per Guthaben"
|
||||
on_DATE_at_TIME: "am %{DATE} um %{TIME},"
|
||||
|
@ -127,7 +127,7 @@ en:
|
||||
no_refund: "No refund"
|
||||
settlement_by_debit_card: "Settlement by debit card"
|
||||
settlement_by_transfer: "Settlement by transfer"
|
||||
settlement_by_check: "Settlement by check"
|
||||
settlement_by_check: "Settlement done at the reception"
|
||||
settlement_done_at_the_reception: "Settlement done at the reception"
|
||||
settlement_by_wallet: "Settlement by wallet"
|
||||
on_DATE_at_TIME: "on %{DATE} at %{TIME},"
|
||||
|
@ -127,7 +127,7 @@ es-MX:
|
||||
no_refund: "Sin devolución"
|
||||
settlement_by_debit_card: "Liquidación por tarjeta de débito"
|
||||
settlement_by_transfer: "Settlement by transfer"
|
||||
settlement_by_check: "Settlement by check"
|
||||
settlement_by_check: "Settlement done at the reception"
|
||||
settlement_done_at_the_reception: "Liquidación realizada en la recepción"
|
||||
settlement_by_wallet: "Liquidación con cartera"
|
||||
on_DATE_at_TIME: "el %{DATE} a las %{TIME},"
|
||||
|
@ -127,7 +127,7 @@ es:
|
||||
no_refund: "Sin devolución"
|
||||
settlement_by_debit_card: "Liquidación por tarjeta de débito"
|
||||
settlement_by_transfer: "Settlement by transfer"
|
||||
settlement_by_check: "Settlement by check"
|
||||
settlement_by_check: "Settlement done at the reception"
|
||||
settlement_done_at_the_reception: "Liquidación realizada en la recepción"
|
||||
settlement_by_wallet: "Liquidación con cartera"
|
||||
on_DATE_at_TIME: "el %{DATE} a las %{TIME},"
|
||||
|
@ -127,7 +127,7 @@ fr:
|
||||
no_refund: "Pas de remboursement"
|
||||
settlement_by_debit_card: "Règlement effectué par carte bancaire"
|
||||
settlement_by_transfer: "Règlement effectué par virement"
|
||||
settlement_by_check: "Règlement effectué par chèque"
|
||||
settlement_by_check: "Règlement effectué à l'accueil"
|
||||
settlement_done_at_the_reception: "Règlement effectué à l'accueil"
|
||||
settlement_by_wallet: "Règlement effectué par porte-monnaie"
|
||||
on_DATE_at_TIME: "le %{DATE} à %{TIME},"
|
||||
|
@ -127,7 +127,7 @@ it:
|
||||
no_refund: "Nessun rimborso"
|
||||
settlement_by_debit_card: "Pagamento con carta di debito"
|
||||
settlement_by_transfer: "Settlement by transfer"
|
||||
settlement_by_check: "Settlement by check"
|
||||
settlement_by_check: "Settlement done at the reception"
|
||||
settlement_done_at_the_reception: "Pagamento effettuato al banco"
|
||||
settlement_by_wallet: "Pagamento effettuato tramite il portafoglio"
|
||||
on_DATE_at_TIME: "il %{DATE} alle %{TIME},"
|
||||
|
@ -127,7 +127,7 @@
|
||||
no_refund: "Ingen refusjon"
|
||||
settlement_by_debit_card: "Oppgjør med betalingskort"
|
||||
settlement_by_transfer: "Settlement by transfer"
|
||||
settlement_by_check: "Settlement by check"
|
||||
settlement_by_check: "Settlement done at the reception"
|
||||
settlement_done_at_the_reception: "Oppgjør i resepsjonen"
|
||||
settlement_by_wallet: "Oppgjør via lommebok"
|
||||
on_DATE_at_TIME: "på %{DATE} kl. %{TIME},"
|
||||
|
@ -127,7 +127,7 @@ pt:
|
||||
no_refund: "Sem reembolso"
|
||||
settlement_by_debit_card: "Liquidação por cartão de débito"
|
||||
settlement_by_transfer: "Settlement by transfer"
|
||||
settlement_by_check: "Settlement by check"
|
||||
settlement_by_check: "Settlement done at the reception"
|
||||
settlement_done_at_the_reception: "Liquidação feita na recepção"
|
||||
settlement_by_wallet: "Liquidação por carteira"
|
||||
on_DATE_at_TIME: "em %{DATE} ás %{TIME},"
|
||||
|
@ -127,7 +127,7 @@ sv:
|
||||
no_refund: "Ingen återbetalning"
|
||||
settlement_by_debit_card: "Betalning med betalkort"
|
||||
settlement_by_transfer: "Settlement by transfer"
|
||||
settlement_by_check: "Settlement by check"
|
||||
settlement_by_check: "Settlement done at the reception"
|
||||
settlement_done_at_the_reception: "Betalning görs i receptionen"
|
||||
settlement_by_wallet: "Betalning med plånbok"
|
||||
on_DATE_at_TIME: "den %{DATE} kl %{TIME},"
|
||||
|
@ -127,7 +127,7 @@ zu:
|
||||
no_refund: "crwdns3355:0crwdne3355:0"
|
||||
settlement_by_debit_card: "crwdns3357:0crwdne3357:0"
|
||||
settlement_by_transfer: "crwdns38172:0crwdne38172:0"
|
||||
settlement_by_check: "crwdns38174:0crwdne38174:0"
|
||||
settlement_by_check: "crwdns38180:0crwdne38180:0"
|
||||
settlement_done_at_the_reception: "crwdns3359:0crwdne3359:0"
|
||||
settlement_by_wallet: "crwdns3361:0crwdne3361:0"
|
||||
on_DATE_at_TIME: "crwdns3363:0%{DATE}crwdnd3363:0%{TIME}crwdne3363:0"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fab-manager",
|
||||
"version": "6.3.15",
|
||||
"version": "6.3.16",
|
||||
"description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.",
|
||||
"keywords": [
|
||||
"fablab",
|
||||
|
@ -30,6 +30,7 @@ class AccountingServiceTest < ActionDispatch::IntegrationTest
|
||||
post '/api/local_payment/confirm_payment', params: {
|
||||
customer_id: @vlonchamp.id,
|
||||
coupon_code: 'GIME3EUR',
|
||||
payment_method: 'cash',
|
||||
items: [
|
||||
{
|
||||
reservation: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user