diff --git a/package-lock.json b/package-lock.json
index 80f2fe463..b972a9fc6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2014,9 +2014,9 @@
}
},
"node_modules/@eslint/eslintrc/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
+ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3823,12 +3823,13 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -3901,12 +3902,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -4034,12 +4036,13 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -4798,9 +4801,10 @@
}
},
"node_modules/ajv": {
- "version": "8.17.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
- "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
+ "license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -7511,10 +7515,11 @@
}
},
"node_modules/eslint/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
+ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -10117,9 +10122,10 @@
"dev": true
},
"node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -13540,10 +13546,11 @@
}
},
"node_modules/url-loader/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
+ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
diff --git a/react/assets/forus-webshop/scss/includes/blocks/block-cms-funds.scss b/react/assets/forus-webshop/scss/includes/blocks/block-cms-funds.scss
index 7bc9760f6..f4ec38476 100644
--- a/react/assets/forus-webshop/scss/includes/blocks/block-cms-funds.scss
+++ b/react/assets/forus-webshop/scss/includes/blocks/block-cms-funds.scss
@@ -7,12 +7,13 @@
.fund-item {
width: 100%;
display: flex;
+ gap: 100px;
padding: 0 0 40px;
border-bottom: 1px solid var(--border-color);
transition: box-shadow 0.4s;
.fund-media {
- width: 52%;
+ width: 42%;
order: 1;
img {
@@ -22,16 +23,16 @@
}
.fund-information {
- width: 50%;
- padding-left: 100px;
text-align: left;
order: 2;
display: flex;
flex-direction: column;
align-self: center;
+ flex: 1;
+ gap: 20px;
.fund-label {
- margin: 0 0 5px;
+ margin: 0 0 -10px;
line-height: 20px;
order: 1;
font-size: var(--cms-funds-label-font-size);
@@ -41,13 +42,13 @@
.fund-title {
font: var(--cms-funds-title-font);
color: var(--cms-funds-title-color);
- margin: 0 0 20px;
+ margin: 0 0;
order: 2;
}
.fund-description {
font: 400 18px/28px var(--base-font);
- margin: 0 0 20px;
+ margin: 0 0;
order: 3;
}
@@ -70,8 +71,6 @@
.fund-information {
order: 1;
- padding-left: 0;
- padding-right: 100px;
}
}
@@ -96,6 +95,7 @@
.fund-item {
display: flex;
+ gap: 0;
flex-wrap: wrap;
flex-direction: column;
flex: 0 1 calc((100% - (calc(var(--gap) * 2))) / 3);
@@ -122,8 +122,6 @@
flex-direction: column;
.fund-label {
- margin: 0 0 15px;
-
.label {
font-size: 12px;
}
@@ -132,14 +130,11 @@
.fund-title {
font: var(--cms-funds-compact-title-font);
color: var(--cms-funds-compact-title-color);
- margin: 0 0 15px;
}
.fund-description {
- margin: 0 0 0;
display: flex;
- flex-grow: 1;
-
+
.block.block-markdown ul, .block.block-markdown p {
&:last-child {
margin-bottom: 0;
@@ -148,8 +143,6 @@
}
.fund-button {
- padding-top: 15px;
-
.fund-button-link {
padding: 0;
display: inline-block;
@@ -184,8 +177,11 @@
}
&.block-cms-funds-2-in-row {
+ --gap: 60px;
+ gap: var(--gap);
+
.fund-item {
- width: calc(calc(100% / 2) - var(--padding));
+ flex: 0 1 calc((100% - (calc(var(--gap)))) / 2);
}
}
}
@@ -195,6 +191,7 @@
gap: 30px;
.fund-item {
+ gap: 0;
padding: 0 0 30px;
flex-direction: column;
@@ -205,15 +202,10 @@
.fund-information {
width: 100%;
- padding: 0;
+ gap: 15px;
.fund-title {
font: 400 20px/26px var(--base-font);
- margin: 0 0 10px;
- }
-
- .fund-description {
- margin: 0 0 10px;
}
.fund-button {
@@ -238,7 +230,6 @@
.fund-information {
order: 2;
- padding: 0;
}
}
}
diff --git a/react/src/dashboard/components/pages/implementation-pages/elements/ImplementationsInlineBlockEditor.tsx b/react/src/dashboard/components/pages/implementation-pages/elements/ImplementationsInlineBlockEditor.tsx
index d4b96a861..fc169a8dd 100644
--- a/react/src/dashboard/components/pages/implementation-pages/elements/ImplementationsInlineBlockEditor.tsx
+++ b/react/src/dashboard/components/pages/implementation-pages/elements/ImplementationsInlineBlockEditor.tsx
@@ -140,7 +140,7 @@ export default function ImplementationsInlineBlockEditor({
id={id}
placeholder={'Paragraaf'}
className={'form-control'}
- value={pageBlock?.description}
+ value={pageBlock?.description ?? ''}
onChange={(e) => setPageBlock({ ...pageBlock, description: e.target.value })}
/>
)
diff --git a/react/src/dashboard/components/pages/implementations-edit/elements/ImplementationsBlockEditorItem.tsx b/react/src/dashboard/components/pages/implementations-edit/elements/ImplementationsBlockEditorItem.tsx
index 303963a0c..b52d62433 100644
--- a/react/src/dashboard/components/pages/implementations-edit/elements/ImplementationsBlockEditorItem.tsx
+++ b/react/src/dashboard/components/pages/implementations-edit/elements/ImplementationsBlockEditorItem.tsx
@@ -95,7 +95,7 @@ export default function ImplementationsBlockEditorItem({
{!isCollapsed && (
-
+
{
+ openModal((modal) => (
+ {
+ modal.close();
+
+ voucherService
+ .sendToEmail(activeOrganization.id, voucher.id)
+ .then(() => pushSuccess('Opgeslagen!'))
+ .catch(pushApiError)
+ .finally(() => setProgress(100));
+ },
+ text: translate('modals.danger_zone.send_voucher_by_email.buttons.confirm'),
+ }}
+ />
+ ));
+ }, [
+ activeOrganization.id,
+ openModal,
+ pushApiError,
+ pushSuccess,
+ setProgress,
+ translate,
+ voucher?.id,
+ voucherService,
+ ]);
+
useEffect(() => {
fetchVoucher();
}, [fetchVoucher]);
@@ -321,6 +356,19 @@ export default function VouchersViewComponent() {
{hasPermission(activeOrganization, Permission.MANAGE_VOUCHERS) && (
+ {voucher.granted &&
+ !voucher.expired &&
+ voucher.state !== 'deactivated' &&
+ !voucher.external &&
+ voucher.fund?.show_qr_code && (
+
+
+ {translate('vouchers.labels.send_to_email')}
+
+ )}
+
{showMakeTransactionButton && fund?.allow_voucher_top_ups && (
diff --git a/react/src/dashboard/i18n/nl/i18n-modals-danger_zone.js b/react/src/dashboard/i18n/nl/i18n-modals-danger_zone.js
index 81d590896..f4001f71c 100644
--- a/react/src/dashboard/i18n/nl/i18n-modals-danger_zone.js
+++ b/react/src/dashboard/i18n/nl/i18n-modals-danger_zone.js
@@ -18,6 +18,7 @@ import remove_mollie_connection from './modals/danger-zone/remove-mollie-connect
import exclude_pre_check_fund from './modals/danger-zone/exclude_pre_check_fund';
import remove_prevalidation_request from './modals/danger-zone/remove-prevalidation-request';
import confirm_extra_payment_refund from './modals/danger-zone/confirm-extra-payment-refund';
+import send_voucher_by_email from './modals/danger-zone/send-voucher-by-email';
export default {
remove_provider_application,
@@ -40,4 +41,5 @@ export default {
exclude_pre_check_fund,
remove_prevalidation_request,
confirm_extra_payment_refund,
+ send_voucher_by_email,
};
diff --git a/react/src/dashboard/i18n/nl/modals/danger-zone/send-voucher-by-email.js b/react/src/dashboard/i18n/nl/modals/danger-zone/send-voucher-by-email.js
new file mode 100644
index 000000000..cd8cf6714
--- /dev/null
+++ b/react/src/dashboard/i18n/nl/modals/danger-zone/send-voucher-by-email.js
@@ -0,0 +1,8 @@
+export default {
+ title: 'QR-code versturen per e-mail',
+ description: 'Weet u zeker dat u de QR-code naar de inwoner wilt versturen?',
+ buttons: {
+ cancel: 'Annuleren',
+ confirm: 'Bevestigen',
+ },
+};
diff --git a/react/src/dashboard/i18n/nl/pages/system-notifications.js b/react/src/dashboard/i18n/nl/pages/system-notifications.js
index 659695efe..ec178c397 100644
--- a/react/src/dashboard/i18n/nl/pages/system-notifications.js
+++ b/react/src/dashboard/i18n/nl/pages/system-notifications.js
@@ -254,8 +254,24 @@ export default {
description: 'Deelnemers ontvangen dit bericht wanneer ze een fysieke pas bestellen.',
},
'notifications_identities.voucher_shared_by_email': {
- title: 'Tegoed verstuurd naar zelf',
- description: 'Deelnemers ontvangen dit bericht wanneer ze een tegoed naar zichzelf sturen.',
+ title: 'Financieel-tegoed naar zichzelf verstuurd',
+ description:
+ 'Deelnemers ontvangen dit bericht wanneer ze de QR-code van een financieel-tegoed naar zichzelf hebben verstuurd.',
+ },
+ 'notifications_identities.product_voucher_shared_by_email': {
+ title: 'Aanbod-tegoed naar zichzelf verstuurd',
+ description:
+ 'Deelnemers ontvangen dit bericht wanneer ze de QR-code van een aanbod-tegoed naar zichzelf hebben verstuurd.',
+ },
+ 'notifications_identities.sponsor_voucher_shared_by_email': {
+ title: 'Financieel-tegoed opnieuw verstuurd',
+ description:
+ 'Deelnemers ontvangen dit bericht als de sponsor het financieel-tegoed opnieuw per e-mail verstuurt.',
+ },
+ 'notifications_identities.sponsor_product_voucher_shared_by_email': {
+ title: 'Aanbod-tegoed opnieuw verstuurd',
+ description:
+ 'Deelnemers ontvangen dit bericht als de sponsor het aanbod-tegoed opnieuw per e-mail verstuurt.',
},
'notifications_identities.voucher_budget_transaction': {
title: 'Transactie van financieel-tegoed',
diff --git a/react/src/dashboard/i18n/nl/pages/vouchers.js b/react/src/dashboard/i18n/nl/pages/vouchers.js
index 303ddb183..f0ceae791 100644
--- a/react/src/dashboard/i18n/nl/pages/vouchers.js
+++ b/react/src/dashboard/i18n/nl/pages/vouchers.js
@@ -46,6 +46,7 @@ export default {
type_voucher: 'Soort tegoed',
type_credit: 'Tegoed waarde',
product: 'Aanbod',
+ send_to_email: 'Verstuur naar e-mail',
},
events: {
created_budget: 'Aangemaakt',
diff --git a/react/src/dashboard/props/models/Fund.tsx b/react/src/dashboard/props/models/Fund.tsx
index c4b0243e8..1c73cfb37 100644
--- a/react/src/dashboard/props/models/Fund.tsx
+++ b/react/src/dashboard/props/models/Fund.tsx
@@ -137,6 +137,7 @@ export default interface Fund {
faq_title?: string;
allow_reimbursements?: boolean;
allow_voucher_payouts?: boolean;
+ allow_voucher_payouts_partial?: boolean;
allow_voucher_payout_count?: number | null;
allow_physical_cards?: boolean;
allow_blocking_vouchers?: boolean;
diff --git a/react/src/dashboard/props/models/Voucher.tsx b/react/src/dashboard/props/models/Voucher.tsx
index 1f51cd9ab..477d5112e 100644
--- a/react/src/dashboard/props/models/Voucher.tsx
+++ b/react/src/dashboard/props/models/Voucher.tsx
@@ -116,4 +116,5 @@ export default interface Voucher {
iban: string;
iban_name: string;
};
+ voucher_payout_partial_amounts?: Array
| null;
}
diff --git a/react/src/dashboard/services/VoucherService.ts b/react/src/dashboard/services/VoucherService.ts
index 18afcdcec..9b8dd951e 100644
--- a/react/src/dashboard/services/VoucherService.ts
+++ b/react/src/dashboard/services/VoucherService.ts
@@ -76,7 +76,7 @@ export class VoucherService {
return this.apiRequest.patch(`${this.prefix}/${organizationId}/sponsor/vouchers/${voucher_id}`, query);
}
- public sendToEmail(organizationId: number, voucher_id: number, email: string): Promise> {
+ public sendToEmail(organizationId: number, voucher_id: number, email?: string): Promise> {
return this.apiRequest.post(`${this.prefix}/${organizationId}/sponsor/vouchers/${voucher_id}/send`, {
email,
});
diff --git a/react/src/webshop/components/elements/cms-blocks/CmsBlocksItem.tsx b/react/src/webshop/components/elements/cms-blocks/CmsBlocksItem.tsx
index 953ebb4c1..fee5138b7 100644
--- a/react/src/webshop/components/elements/cms-blocks/CmsBlocksItem.tsx
+++ b/react/src/webshop/components/elements/cms-blocks/CmsBlocksItem.tsx
@@ -1,7 +1,6 @@
import React from 'react';
import Markdown from '../markdown/Markdown';
import ImplementationPageBlock from '../../../props/models/ImplementationPageBlock';
-import useAssetUrl from '../../../hooks/useAssetUrl';
import Label from '../label/Label';
export default function CmsBlocksItem({
@@ -11,16 +10,13 @@ export default function CmsBlocksItem({
block: ImplementationPageBlock;
blocksPerRow: number;
}) {
- const assetUrl = useAssetUrl();
-
return (
-
-

-
+ {block.media?.sizes?.public && (
+
+

+
+ )}
{block.title &&
{block.title}
}
{block.label && (
diff --git a/react/src/webshop/components/elements/cms-blocks/CmsBlocksItemLink.tsx b/react/src/webshop/components/elements/cms-blocks/CmsBlocksItemLink.tsx
index 365901650..6c2fc3ebf 100644
--- a/react/src/webshop/components/elements/cms-blocks/CmsBlocksItemLink.tsx
+++ b/react/src/webshop/components/elements/cms-blocks/CmsBlocksItemLink.tsx
@@ -1,24 +1,20 @@
import React from 'react';
import Markdown from '../markdown/Markdown';
import ImplementationPageBlock from '../../../props/models/ImplementationPageBlock';
-import useAssetUrl from '../../../hooks/useAssetUrl';
import Label from '../label/Label';
export default function CmsBlocksItemLink({ block }: { block: ImplementationPageBlock }) {
- const assetUrl = useAssetUrl();
-
return (
-
-

-
+ {block.media?.sizes?.public && (
+
+

+
+ )}
{block.title &&
{block.title}
}
{block.label && (
diff --git a/react/src/webshop/components/modals/ModalVoucherPayout.tsx b/react/src/webshop/components/modals/ModalVoucherPayout.tsx
index 9a3e39402..bacd59e15 100644
--- a/react/src/webshop/components/modals/ModalVoucherPayout.tsx
+++ b/react/src/webshop/components/modals/ModalVoucherPayout.tsx
@@ -93,9 +93,33 @@ export default function ModalVoucherPayout({
const selectedVoucherId = selectedVoucherItem?.id;
const updateForm = form.update;
+ const partialPayoutAmounts = useMemo(() => {
+ return selectedVoucherItem?.voucher_payout_partial_amounts;
+ }, [selectedVoucherItem?.voucher_payout_partial_amounts]);
+
+ const partialPayoutOptions = useMemo(() => {
+ if (!Array.isArray(partialPayoutAmounts)) {
+ return [];
+ }
+
+ return partialPayoutAmounts.map((amount) => {
+ const amountNumber = parseFloat(amount);
+ const name = isNaN(amountNumber) ? amount : currencyFormat(amountNumber);
+
+ return {
+ id: amount,
+ name,
+ };
+ });
+ }, [partialPayoutAmounts]);
+
const fixedPayoutAmount = useMemo(() => {
+ if (Array.isArray(partialPayoutAmounts)) {
+ return null;
+ }
+
return selectedVoucherItem?.fund?.voucher_payout_fixed_amount;
- }, [selectedVoucherItem?.fund?.voucher_payout_fixed_amount]);
+ }, [partialPayoutAmounts, selectedVoucherItem?.fund?.voucher_payout_fixed_amount]);
const payoutCountWarning = useMemo(() => {
if (!selectedVoucherItem) {
@@ -117,11 +141,23 @@ export default function ModalVoucherPayout({
return null;
}, [selectedVoucherItem, translate]);
+ const payoutPartialWarning = useMemo(() => {
+ if (!Array.isArray(partialPayoutAmounts)) {
+ return null;
+ }
+
+ return partialPayoutAmounts.length === 0 ? translate('voucher.payout.warning_no_partial_amounts') : null;
+ }, [partialPayoutAmounts, translate]);
+
const payoutAmountWarning = useMemo(() => {
if (!selectedVoucherItem) {
return null;
}
+ if (Array.isArray(partialPayoutAmounts)) {
+ return null;
+ }
+
const voucherAmount = parseFloat(selectedVoucherItem?.amount) || 0;
if (fixedPayoutAmount !== null && fixedPayoutAmount !== undefined) {
@@ -139,21 +175,26 @@ export default function ModalVoucherPayout({
min: currencyFormat(0.1),
})
: null;
- }, [fixedPayoutAmount, selectedVoucherItem, translate]);
+ }, [fixedPayoutAmount, partialPayoutAmounts, selectedVoucherItem, translate]);
- const warningMessage = payoutCountWarning || payoutAmountWarning;
+ const warningMessage = payoutPartialWarning || payoutCountWarning || payoutAmountWarning;
useEffect(() => {
if (!selectedVoucherId) {
return;
}
+ if (Array.isArray(partialPayoutAmounts)) {
+ updateForm({ amount: partialPayoutAmounts[0] || '' });
+ return;
+ }
+
if (fixedPayoutAmount !== null && fixedPayoutAmount !== undefined) {
updateForm({ amount: fixedPayoutAmount });
} else {
updateForm({ amount: '' });
}
- }, [fixedPayoutAmount, selectedVoucherId, updateForm]);
+ }, [fixedPayoutAmount, partialPayoutAmounts, selectedVoucherId, updateForm]);
useEffect(() => {
if (!fundRequestAccounts?.length) {
@@ -275,6 +316,23 @@ export default function ModalVoucherPayout({
required={true}
error={form.errors?.amount}
input={(id) => {
+ if (Array.isArray(partialPayoutAmounts)) {
+ return (
+
form.update({ amount })}
+ disabled={partialPayoutOptions.length === 0}
+ dusk="voucherPayoutAmount"
+ />
+ );
+ }
+
if (fixedPayoutAmount !== null && fixedPayoutAmount !== undefined) {
const amountNumber = parseFloat(fixedPayoutAmount);
const displayValue = isNaN(amountNumber)
diff --git a/react/src/webshop/i18n/nl/pages/voucher.mjs b/react/src/webshop/i18n/nl/pages/voucher.mjs
index 1cfd34af1..4907059f0 100644
--- a/react/src/webshop/i18n/nl/pages/voucher.mjs
+++ b/react/src/webshop/i18n/nl/pages/voucher.mjs
@@ -115,6 +115,7 @@ export default {
accept_compliance_rules_info:
'Ik verklaar dat:
- ik het geld alleen gebruik voor deze activiteit;
- ik het geld gebruik volgens de regels van de regeling;
- ik begrijp dat ik het geld moet terugbetalen als ik het niet juist gebruik.
',
warning_count_reached: 'Het maximale aantal uitbetalingen voor dit tegoed is bereikt.',
+ warning_no_partial_amounts: 'Er is geen uitbetalingsbedrag beschikbaar voor dit tegoed.',
warning_not_enough_amount_min: 'Dit tegoed moet minimaal {{ min }} bevatten voor een uitbetaling.',
warning_not_enough_amount_fixed: 'Dit tegoed moet minimaal {{ amount }} bevatten voor een uitbetaling.',
submit: 'Overboeken',
diff --git a/react/src/webshop/i18n/translated/ar.json b/react/src/webshop/i18n/translated/ar.json
index 74dcd10dd..3558e7c59 100644
--- a/react/src/webshop/i18n/translated/ar.json
+++ b/react/src/webshop/i18n/translated/ar.json
@@ -2154,7 +2154,8 @@
"warning_not_enough_amount_fixed": "يجب أن يتضمن هذا الرصيد {{ amount }} على الأقل للدفع.",
"warning_not_enough_amount_min": "يجب أن يتضمن هذا الرصيد {{ min }} على الأقل للدفع.",
"accept_compliance_rules_info": "أقر بأنني:
- أنا أستخدم الأموال لهذا النشاط فقط;
- أنا أستخدم المال وفقاً لقواعد البرنامج;
- أفهم أنني يجب أن أسدد الأموال إذا لم أستخدمها بشكل صحيح.
",
- "accept_compliance_rules": "أوافق على الشروط والأحكام المذكورة أعلاه."
+ "accept_compliance_rules": "أوافق على الشروط والأحكام المذكورة أعلاه.",
+ "warning_no_partial_amounts": "لا يوجد مبلغ مدفوعات متاح لهذا الرصيد."
}
},
"vouchers": {
@@ -2692,7 +2693,7 @@
"title": "العنوان"
},
"title": "بيانات الإعلان",
- "code": "الرقم: #: الرمز"
+ "code": "الرقم: #{{code}}"
},
"empty": {
"button": "إرسال القسيمة",
diff --git a/react/src/webshop/i18n/translated/de.json b/react/src/webshop/i18n/translated/de.json
index 3123a743f..cc7a9ff8e 100644
--- a/react/src/webshop/i18n/translated/de.json
+++ b/react/src/webshop/i18n/translated/de.json
@@ -2719,7 +2719,7 @@
"title": "Titel"
},
"title": "Daten der Erklärung",
- "code": "Nummer: #:code"
+ "code": "Nummer: #{{code}}"
},
"empty": {
"button": "Coupon einreichen",
@@ -3510,7 +3510,8 @@
"warning_not_enough_amount_fixed": "Dieses Guthaben muss mindestens {{ amount }} für eine Auszahlung umfassen.",
"warning_not_enough_amount_min": "Dieses Guthaben muss mindestens {{ min }} für eine Auszahlung umfassen.",
"accept_compliance_rules_info": "Ich erkläre, dass:
- Ich verwende das Geld nur für diese Aktivität;
- Ich verwende das Geld gemäß den Regeln des Programms;
- ich verstehe, dass ich das Geld zurückzahlen muss, wenn ich es nicht ordnungsgemäß verwende.
",
- "accept_compliance_rules": "Ich erkläre mich mit den oben genannten Bestimmungen und Bedingungen einverstanden."
+ "accept_compliance_rules": "Ich erkläre mich mit den oben genannten Bestimmungen und Bedingungen einverstanden.",
+ "warning_no_partial_amounts": "Für diesen Kredit ist kein Auszahlungsbetrag verfügbar."
}
},
"vouchers": {
diff --git a/react/src/webshop/i18n/translated/en-US.json b/react/src/webshop/i18n/translated/en-US.json
index d5a0ca2b9..0275da3b0 100644
--- a/react/src/webshop/i18n/translated/en-US.json
+++ b/react/src/webshop/i18n/translated/en-US.json
@@ -1855,7 +1855,8 @@
"warning_not_enough_amount_fixed": "This credit must include a minimum of {{ amount }} for a payout.",
"warning_not_enough_amount_min": "This credit must include a minimum of {{ min }} for a payout.",
"accept_compliance_rules_info": "I declare that:
- I am using the money only for this activity;
- I am using the money according to the rules of the scheme;
- I understand that I must repay the money if I do not use it correctly.
",
- "accept_compliance_rules": "I agree to the above terms and conditions."
+ "accept_compliance_rules": "I agree to the above terms and conditions.",
+ "warning_no_partial_amounts": "There is no payout amount available for this credit."
}
},
"vouchers": {
@@ -2389,7 +2390,7 @@
"title": "Title"
},
"title": "Claim data",
- "code": "Number: #:code"
+ "code": "Number: #{{code}}"
},
"empty": {
"button": "Submit coupon",
diff --git a/react/src/webshop/i18n/translated/fr.json b/react/src/webshop/i18n/translated/fr.json
index 3a8a6d667..9e328ef12 100644
--- a/react/src/webshop/i18n/translated/fr.json
+++ b/react/src/webshop/i18n/translated/fr.json
@@ -2719,7 +2719,7 @@
"title": "Titre"
},
"title": "Données de la déclaration",
- "code": "Nombre : #:code"
+ "code": "Nombre : #{{code}}"
},
"empty": {
"button": "Soumettre un coupon",
@@ -3510,7 +3510,8 @@
"warning_not_enough_amount_fixed": "Ce crédit doit comprendre au moins {{ amount }} pour un paiement.",
"warning_not_enough_amount_min": "Ce crédit doit comprendre au moins {{ min }} pour un paiement.",
"accept_compliance_rules_info": "Je déclare que :
- J'utilise l'argent uniquement pour cette activité ;
- J'utilise l'argent conformément aux règles du programme ;
- Je comprends que je dois rembourser l'argent si je ne l'utilise pas correctement.
",
- "accept_compliance_rules": "J'accepte les termes et conditions ci-dessus."
+ "accept_compliance_rules": "J'accepte les termes et conditions ci-dessus.",
+ "warning_no_partial_amounts": "Aucun montant de remboursement n'est disponible pour ce crédit."
}
},
"vouchers": {
diff --git a/react/src/webshop/i18n/translated/pl.json b/react/src/webshop/i18n/translated/pl.json
index d67406258..1ad2eded7 100644
--- a/react/src/webshop/i18n/translated/pl.json
+++ b/react/src/webshop/i18n/translated/pl.json
@@ -2719,7 +2719,7 @@
"title": "Tytuł"
},
"title": "Dane deklaracji",
- "code": "Numer: #:kod"
+ "code": "Numer: #{{code}}"
},
"empty": {
"button": "Prześlij kupon",
@@ -3510,7 +3510,8 @@
"warning_not_enough_amount_fixed": "Kredyt ten musi obejmować co najmniej {{ amount }} do wypłaty.",
"warning_not_enough_amount_min": "Kredyt ten musi obejmować co najmniej {{ min }} do wypłaty.",
"accept_compliance_rules_info": "Oświadczam, że:
- Wykorzystuję pieniądze wyłącznie na tę działalność;
- wykorzystuję pieniądze zgodnie z zasadami programu;
- Rozumiem, że muszę zwrócić pieniądze, jeśli nie wykorzystam ich prawidłowo.
",
- "accept_compliance_rules": "Zgadzam się na powyższe warunki."
+ "accept_compliance_rules": "Zgadzam się na powyższe warunki.",
+ "warning_no_partial_amounts": "Kwota wypłaty nie jest dostępna dla tego kredytu."
}
},
"vouchers": {
diff --git a/react/src/webshop/i18n/translated/ru.json b/react/src/webshop/i18n/translated/ru.json
index 0b529cf9c..bc9f7ef46 100644
--- a/react/src/webshop/i18n/translated/ru.json
+++ b/react/src/webshop/i18n/translated/ru.json
@@ -2719,7 +2719,7 @@
"title": "Название"
},
"title": "Данные декларации",
- "code": "Номер: #:код"
+ "code": "Номер: #{{code}}"
},
"empty": {
"button": "Отправить купон",
@@ -3510,7 +3510,8 @@
"warning_not_enough_amount_fixed": "Этот кредит должен включать в себя как минимум {{ amount }} для выплаты.",
"warning_not_enough_amount_min": "Этот кредит должен включать в себя как минимум {{ min }} для выплаты.",
"accept_compliance_rules_info": "Я заявляю, что:
- Я использую деньги только для этой деятельности;
- Я использую деньги в соответствии с правилами программы;
- Я понимаю, что должен вернуть деньги, если использую их неправильно.
",
- "accept_compliance_rules": "Я согласен с вышеуказанными условиями и положениями."
+ "accept_compliance_rules": "Я согласен с вышеуказанными условиями и положениями.",
+ "warning_no_partial_amounts": "Сумма выплаты по этому кредиту не предусмотрена."
}
},
"vouchers": {
diff --git a/react/src/webshop/i18n/translated/tr.json b/react/src/webshop/i18n/translated/tr.json
index 63983e181..6461fa7ff 100644
--- a/react/src/webshop/i18n/translated/tr.json
+++ b/react/src/webshop/i18n/translated/tr.json
@@ -2154,7 +2154,8 @@
"warning_not_enough_amount_fixed": "Bu kredi, ödeme için en az {{ amount }} adresini içermelidir.",
"warning_not_enough_amount_min": "Bu kredi, ödeme için en az {{ min }} adresini içermelidir.",
"accept_compliance_rules_info": "Bunu beyan ederim:
- Parayı sadece bu faaliyet için kullanıyorum;
- Parayı programın kurallarına uygun olarak kullanıyorum;
- Parayı doğru kullanmadığım takdirde geri ödemem gerektiğini anlıyorum.
",
- "accept_compliance_rules": "Yukarıdaki hüküm ve koşulları kabul ediyorum."
+ "accept_compliance_rules": "Yukarıdaki hüküm ve koşulları kabul ediyorum.",
+ "warning_no_partial_amounts": "Bu kredi için herhangi bir ödeme tutarı mevcut değildir."
}
},
"vouchers": {
@@ -2692,7 +2693,7 @@
"title": "Başlık"
},
"title": "Beyan verileri",
- "code": "Numara: #:code"
+ "code": "Numara: #{{code}}"
},
"empty": {
"button": "Kupon gönder",
diff --git a/react/src/webshop/i18n/translated/uk.json b/react/src/webshop/i18n/translated/uk.json
index 0c33ee1c8..d62100687 100644
--- a/react/src/webshop/i18n/translated/uk.json
+++ b/react/src/webshop/i18n/translated/uk.json
@@ -2719,7 +2719,7 @@
"title": "Назва"
},
"title": "Дані декларації",
- "code": "Номер: #:код"
+ "code": "Номер: #{{code}}"
},
"empty": {
"button": "Надіслати купон",
@@ -3510,7 +3510,8 @@
"warning_not_enough_amount_fixed": "Цей кредит повинен містити щонайменше {{ amount }} для виплати.",
"warning_not_enough_amount_min": "Цей кредит повинен містити щонайменше {{ min }} для виплати.",
"accept_compliance_rules_info": "Я заявляю про це:
- Я використовую гроші тільки для цієї діяльності;
- Я використовую гроші відповідно до правил схеми;
- Я розумію, що повинен повернути гроші, якщо використаю їх не за призначенням.
",
- "accept_compliance_rules": "Я погоджуюся з вищезазначеними умовами та положеннями."
+ "accept_compliance_rules": "Я погоджуюся з вищезазначеними умовами та положеннями.",
+ "warning_no_partial_amounts": "Сума виплат за цим кредитом не передбачена."
}
},
"vouchers": {
diff --git a/translations/cache/cache.json b/translations/cache/cache.json
index 15cc2bd93..1aaac7e04 100644
--- a/translations/cache/cache.json
+++ b/translations/cache/cache.json
@@ -7645,7 +7645,7 @@
],
[
"reimbursements.details.code",
- "Nummer: #:code"
+ "Nummer: #{{code}}"
],
[
"reimbursements.details.labels.amount",
@@ -9407,6 +9407,10 @@
"voucher.payout.warning_count_reached",
"Het maximale aantal uitbetalingen voor dit tegoed is bereikt."
],
+ [
+ "voucher.payout.warning_no_partial_amounts",
+ "Er is geen uitbetalingsbedrag beschikbaar voor dit tegoed."
+ ],
[
"voucher.payout.warning_not_enough_amount_fixed",
"Dit tegoed moet minimaal {{ amount }} bevatten voor een uitbetaling."