mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-26 06:47:17 +10:00
Improve wrong currency handling
This commit is contained in:
parent
22b0aa512b
commit
186005dfd3
6 changed files with 139 additions and 94 deletions
|
|
@ -1,10 +1,13 @@
|
|||
import Decimal from 'decimal.js';
|
||||
import { types } from '../../util/sdkLoader';
|
||||
import * as propTypes from '../../util/propTypes';
|
||||
import config from '../../config';
|
||||
import BookingBreakdown from './BookingBreakdown';
|
||||
|
||||
const { UUID, Money } = types;
|
||||
|
||||
const CURRENCY = config.currency;
|
||||
|
||||
const exampleBooking = attributes => {
|
||||
return {
|
||||
id: new UUID('example-booking'),
|
||||
|
|
@ -41,14 +44,14 @@ export const Checkout = {
|
|||
props: {
|
||||
userRole: 'customer',
|
||||
transaction: exampleTransaction({
|
||||
payinTotal: new Money(9000, 'USD'),
|
||||
payoutTotal: new Money(9000, 'USD'),
|
||||
payinTotal: new Money(9000, CURRENCY),
|
||||
payoutTotal: new Money(9000, CURRENCY),
|
||||
lineItems: [
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(2),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(9000, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(9000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
],
|
||||
|
|
@ -65,14 +68,14 @@ export const CustomerOrder = {
|
|||
props: {
|
||||
userRole: 'customer',
|
||||
transaction: exampleTransaction({
|
||||
payinTotal: new Money(9000, 'USD'),
|
||||
payoutTotal: new Money(9000, 'USD'),
|
||||
payinTotal: new Money(9000, CURRENCY),
|
||||
payoutTotal: new Money(9000, CURRENCY),
|
||||
lineItems: [
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(2),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(9000, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(9000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
],
|
||||
|
|
@ -89,20 +92,20 @@ export const ProviderSale = {
|
|||
props: {
|
||||
userRole: 'provider',
|
||||
transaction: exampleTransaction({
|
||||
payinTotal: new Money(9000, 'USD'),
|
||||
payoutTotal: new Money(7000, 'USD'),
|
||||
payinTotal: new Money(9000, CURRENCY),
|
||||
payoutTotal: new Money(7000, CURRENCY),
|
||||
lineItems: [
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(2),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(9000, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(9000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
{
|
||||
code: 'line-item/provider-commission',
|
||||
unitPrice: new Money(-2000, 'USD'),
|
||||
lineTotal: new Money(-2000, 'USD'),
|
||||
unitPrice: new Money(-2000, CURRENCY),
|
||||
lineTotal: new Money(-2000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
],
|
||||
|
|
@ -119,20 +122,20 @@ export const ProviderSaleZeroCommission = {
|
|||
props: {
|
||||
userRole: 'provider',
|
||||
transaction: exampleTransaction({
|
||||
payinTotal: new Money(9000, 'USD'),
|
||||
payoutTotal: new Money(9000, 'USD'),
|
||||
payinTotal: new Money(9000, CURRENCY),
|
||||
payoutTotal: new Money(9000, CURRENCY),
|
||||
lineItems: [
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(2),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(9000, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(9000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
{
|
||||
code: 'line-item/provider-commission',
|
||||
unitPrice: new Money(0, 'USD'),
|
||||
lineTotal: new Money(0, 'USD'),
|
||||
unitPrice: new Money(0, CURRENCY),
|
||||
lineTotal: new Money(0, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
],
|
||||
|
|
@ -149,20 +152,20 @@ export const ProviderSaleSingleNight = {
|
|||
props: {
|
||||
userRole: 'provider',
|
||||
transaction: exampleTransaction({
|
||||
payinTotal: new Money(4500, 'USD'),
|
||||
payoutTotal: new Money(2500, 'USD'),
|
||||
payinTotal: new Money(4500, CURRENCY),
|
||||
payoutTotal: new Money(2500, CURRENCY),
|
||||
lineItems: [
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(1),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(4500, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(4500, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
{
|
||||
code: 'line-item/provider-commission',
|
||||
unitPrice: new Money(-2000, 'USD'),
|
||||
lineTotal: new Money(-2000, 'USD'),
|
||||
unitPrice: new Money(-2000, CURRENCY),
|
||||
lineTotal: new Money(-2000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
],
|
||||
|
|
@ -180,20 +183,20 @@ export const ProviderSalePreauthorized = {
|
|||
userRole: 'provider',
|
||||
transaction: exampleTransaction({
|
||||
lastTransition: propTypes.TX_TRANSITION_PREAUTHORIZE,
|
||||
payinTotal: new Money(4500, 'USD'),
|
||||
payoutTotal: new Money(2500, 'USD'),
|
||||
payinTotal: new Money(4500, CURRENCY),
|
||||
payoutTotal: new Money(2500, CURRENCY),
|
||||
lineItems: [
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(1),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(4500, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(4500, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
{
|
||||
code: 'line-item/provider-commission',
|
||||
unitPrice: new Money(-2000, 'USD'),
|
||||
lineTotal: new Money(-2000, 'USD'),
|
||||
unitPrice: new Money(-2000, CURRENCY),
|
||||
lineTotal: new Money(-2000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
],
|
||||
|
|
@ -211,20 +214,20 @@ export const ProviderSaleAccepted = {
|
|||
userRole: 'provider',
|
||||
transaction: exampleTransaction({
|
||||
lastTransition: propTypes.TX_TRANSITION_ACCEPT,
|
||||
payinTotal: new Money(4500, 'USD'),
|
||||
payoutTotal: new Money(2500, 'USD'),
|
||||
payinTotal: new Money(4500, CURRENCY),
|
||||
payoutTotal: new Money(2500, CURRENCY),
|
||||
lineItems: [
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(1),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(4500, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(4500, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
{
|
||||
code: 'line-item/provider-commission',
|
||||
unitPrice: new Money(-2000, 'USD'),
|
||||
lineTotal: new Money(-2000, 'USD'),
|
||||
unitPrice: new Money(-2000, CURRENCY),
|
||||
lineTotal: new Money(-2000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
],
|
||||
|
|
@ -242,20 +245,20 @@ export const ProviderSaleDeclined = {
|
|||
userRole: 'provider',
|
||||
transaction: exampleTransaction({
|
||||
lastTransition: propTypes.TX_TRANSITION_DECLINE,
|
||||
payinTotal: new Money(4500, 'USD'),
|
||||
payoutTotal: new Money(2500, 'USD'),
|
||||
payinTotal: new Money(4500, CURRENCY),
|
||||
payoutTotal: new Money(2500, CURRENCY),
|
||||
lineItems: [
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(1),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(4500, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(4500, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
{
|
||||
code: 'line-item/provider-commission',
|
||||
unitPrice: new Money(-2000, 'USD'),
|
||||
lineTotal: new Money(-2000, 'USD'),
|
||||
unitPrice: new Money(-2000, CURRENCY),
|
||||
lineTotal: new Money(-2000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
],
|
||||
|
|
@ -273,20 +276,20 @@ export const ProviderSaleAutoDeclined = {
|
|||
userRole: 'provider',
|
||||
transaction: exampleTransaction({
|
||||
lastTransition: propTypes.TX_TRANSITION_AUTO_DECLINE,
|
||||
payinTotal: new Money(4500, 'USD'),
|
||||
payoutTotal: new Money(2500, 'USD'),
|
||||
payinTotal: new Money(4500, CURRENCY),
|
||||
payoutTotal: new Money(2500, CURRENCY),
|
||||
lineItems: [
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(1),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(4500, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(4500, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
{
|
||||
code: 'line-item/provider-commission',
|
||||
unitPrice: new Money(-2000, 'USD'),
|
||||
lineTotal: new Money(-2000, 'USD'),
|
||||
unitPrice: new Money(-2000, CURRENCY),
|
||||
lineTotal: new Money(-2000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
],
|
||||
|
|
@ -304,20 +307,20 @@ export const ProviderSaleDelivered = {
|
|||
userRole: 'provider',
|
||||
transaction: exampleTransaction({
|
||||
lastTransition: propTypes.TX_TRANSITION_MARK_DELIVERED,
|
||||
payinTotal: new Money(4500, 'USD'),
|
||||
payoutTotal: new Money(2500, 'USD'),
|
||||
payinTotal: new Money(4500, CURRENCY),
|
||||
payoutTotal: new Money(2500, CURRENCY),
|
||||
lineItems: [
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(1),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(4500, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(4500, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
{
|
||||
code: 'line-item/provider-commission',
|
||||
unitPrice: new Money(-2000, 'USD'),
|
||||
lineTotal: new Money(-2000, 'USD'),
|
||||
unitPrice: new Money(-2000, CURRENCY),
|
||||
lineTotal: new Money(-2000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
],
|
||||
|
|
@ -335,35 +338,35 @@ export const ProviderSaleCanceled = {
|
|||
userRole: 'provider',
|
||||
transaction: exampleTransaction({
|
||||
lastTransition: propTypes.TX_TRANSITION_CANCEL,
|
||||
payinTotal: new Money(0, 'USD'),
|
||||
payoutTotal: new Money(0, 'USD'),
|
||||
payinTotal: new Money(0, CURRENCY),
|
||||
payoutTotal: new Money(0, CURRENCY),
|
||||
lineItems: [
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(1),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(4500, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(4500, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
{
|
||||
code: 'line-item/night',
|
||||
quantity: new Decimal(-1),
|
||||
unitPrice: new Money(4500, 'USD'),
|
||||
lineTotal: new Money(-4500, 'USD'),
|
||||
unitPrice: new Money(4500, CURRENCY),
|
||||
lineTotal: new Money(-4500, CURRENCY),
|
||||
reversal: true,
|
||||
},
|
||||
{
|
||||
code: 'line-item/provider-commission',
|
||||
quantity: new Decimal(1),
|
||||
unitPrice: new Money(-2000, 'USD'),
|
||||
lineTotal: new Money(-2000, 'USD'),
|
||||
unitPrice: new Money(-2000, CURRENCY),
|
||||
lineTotal: new Money(-2000, CURRENCY),
|
||||
reversal: false,
|
||||
},
|
||||
{
|
||||
code: 'line-item/provider-commission',
|
||||
quantity: new Decimal(-1),
|
||||
unitPrice: new Money(2000, 'USD'),
|
||||
lineTotal: new Money(-2000, 'USD'),
|
||||
unitPrice: new Money(2000, CURRENCY),
|
||||
lineTotal: new Money(-2000, CURRENCY),
|
||||
reversal: true,
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -9,17 +9,22 @@ import { currencyConfig } from '../../util/test-data';
|
|||
import * as validators from '../../util/validators';
|
||||
import CurrencyInputField, { CurrencyInput } from './CurrencyInputField';
|
||||
|
||||
const defaultConfig = {
|
||||
const currencyConfigUSD = {
|
||||
...currencyConfig,
|
||||
currency: 'USD',
|
||||
};
|
||||
|
||||
const currencyConfigEUR = {
|
||||
...currencyConfig,
|
||||
currency: 'EUR',
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
const onChange = price => console.log('CurrencyInput - value:', price);
|
||||
|
||||
// Different locales need to be initialized before their currency formatting is in use
|
||||
const CurrencyInputWithIntl = ({ locale, ...rest }) => {
|
||||
if (locale === 'en-US') {
|
||||
if (locale === 'en') {
|
||||
addLocaleData([...en]);
|
||||
} else {
|
||||
addLocaleData([...fi]);
|
||||
|
|
@ -38,22 +43,39 @@ CurrencyInputWithIntl.propTypes = {
|
|||
locale: string.isRequired,
|
||||
};
|
||||
|
||||
// Empty field with en-US locale
|
||||
export const EmptyWithEnUS = {
|
||||
export const EmptyWithEnUSD = {
|
||||
component: CurrencyInputWithIntl,
|
||||
props: {
|
||||
currencyConfig: defaultConfig,
|
||||
locale: 'en-US',
|
||||
currencyConfig: currencyConfigUSD,
|
||||
locale: 'en',
|
||||
},
|
||||
group: 'custom inputs',
|
||||
};
|
||||
|
||||
// Default value with fi-FI locale
|
||||
export const defaultValueWithFiFI = {
|
||||
export const defaultValueWithEnUSD = {
|
||||
component: CurrencyInputWithIntl,
|
||||
props: {
|
||||
currencyConfig: { ...defaultConfig, currency: 'EUR' },
|
||||
locale: 'fi-FI',
|
||||
currencyConfig: currencyConfigUSD,
|
||||
locale: 'en',
|
||||
defaultValue: 9999.99,
|
||||
},
|
||||
group: 'custom inputs',
|
||||
};
|
||||
|
||||
export const EmptyWithFiEUR = {
|
||||
component: CurrencyInputWithIntl,
|
||||
props: {
|
||||
currencyConfig: currencyConfigEUR,
|
||||
locale: 'fi',
|
||||
},
|
||||
group: 'custom inputs',
|
||||
};
|
||||
|
||||
export const defaultValueWithFiEUR = {
|
||||
component: CurrencyInputWithIntl,
|
||||
props: {
|
||||
currencyConfig: currencyConfigEUR,
|
||||
locale: 'fi',
|
||||
defaultValue: 9999.99,
|
||||
},
|
||||
group: 'custom inputs',
|
||||
|
|
@ -71,7 +93,7 @@ const FormComponent = props => {
|
|||
id={`${form}.price`}
|
||||
label="Set price:"
|
||||
placeholder="Type in amount in EUR..."
|
||||
currencyConfig={{ ...defaultConfig, currency: 'EUR' }}
|
||||
currencyConfig={currencyConfigEUR}
|
||||
validate={required}
|
||||
/>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -51,8 +51,15 @@ class CurrencyInputComponent extends Component {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
const { currencyConfig, defaultValue, input, intl } = props;
|
||||
const initialValue =
|
||||
input.value instanceof types.Money ? convertMoneyToNumber(input.value) : defaultValue;
|
||||
const initialValueIsMoney = input.value instanceof types.Money;
|
||||
|
||||
if (initialValueIsMoney && input.value.currency !== currencyConfig.currency) {
|
||||
const e = new Error('Value currency different from marketplace currency');
|
||||
log.error(e, 'currency-input-invalid-currency', { currencyConfig, inputValue: input.value });
|
||||
throw e;
|
||||
}
|
||||
|
||||
const initialValue = initialValueIsMoney ? convertMoneyToNumber(input.value) : defaultValue;
|
||||
const hasInitialValue = typeof initialValue === 'number' && !isNaN(initialValue);
|
||||
|
||||
// We need to handle number format - some locales use dots and some commas as decimal separator
|
||||
|
|
@ -82,11 +89,7 @@ class CurrencyInputComponent extends Component {
|
|||
usesComma,
|
||||
};
|
||||
} catch (e) {
|
||||
log.error(e, 'currency-input-init-failed', {
|
||||
currencyConfig: currencyConfig,
|
||||
defaultValue: defaultValue,
|
||||
initialValue: initialValue,
|
||||
});
|
||||
log.error(e, 'currency-input-init-failed', { currencyConfig, defaultValue, initialValue });
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,3 +20,7 @@
|
|||
margin-bottom: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
.priceCurrencyInvalid {
|
||||
color: var(--failColor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import { createSlug } from '../../util/urlHelpers';
|
|||
import { NamedLink } from '../../components';
|
||||
import { EditListingPricingForm } from '../../containers';
|
||||
import { ensureListing } from '../../util/data';
|
||||
import { types } from '../../util/sdkLoader';
|
||||
import config from '../../config';
|
||||
|
||||
import css from './EditListingPricingPanel.css';
|
||||
|
||||
|
|
@ -40,19 +42,29 @@ const EditListingPricingPanel = props => {
|
|||
<FormattedMessage id="EditListingPricingPanel.createListingTitle" />
|
||||
);
|
||||
|
||||
const priceCurrencyValid =
|
||||
price instanceof types.Money ? price.currency === config.currency : true;
|
||||
const form = priceCurrencyValid ? (
|
||||
<EditListingPricingForm
|
||||
className={css.form}
|
||||
initialValues={{ price }}
|
||||
onSubmit={onSubmit}
|
||||
onChange={onChange}
|
||||
saveActionMsg={submitButtonText}
|
||||
updated={panelUpdated}
|
||||
updateError={errors.updateListingError}
|
||||
updateInProgress={updateInProgress}
|
||||
/>
|
||||
) : (
|
||||
<div className={css.priceCurrencyInvalid}>
|
||||
<FormattedMessage id="EditListingPricingPanel.listingPriceCurrencyInvalid" />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
<h1 className={css.title}>{panelTitle}</h1>
|
||||
<EditListingPricingForm
|
||||
className={css.form}
|
||||
initialValues={{ price }}
|
||||
onSubmit={onSubmit}
|
||||
onChange={onChange}
|
||||
saveActionMsg={submitButtonText}
|
||||
updated={panelUpdated}
|
||||
updateError={errors.updateListingError}
|
||||
updateInProgress={updateInProgress}
|
||||
/>
|
||||
{form}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@
|
|||
"EditListingPricingForm.priceRequired": "You need to add a valid price.",
|
||||
"EditListingPricingForm.updateFailed": "Failed to update listing. Please try again.",
|
||||
"EditListingPricingPanel.createListingTitle": "How much does it cost?",
|
||||
"EditListingPricingPanel.listingPriceCurrencyInvalid": "Listing currency is different from the marketplace currency. You cannot edit the price.",
|
||||
"EditListingPricingPanel.title": "Edit the pricing of {listingTitle}",
|
||||
"EditListingWizard.saveEditDescription": "Save description",
|
||||
"EditListingWizard.saveEditLocation": "Save location",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue