Extract transaction related code to its own util file

from types.js
This commit is contained in:
Vesa Luusua 2019-01-10 17:51:13 +02:00
parent e56864050f
commit a7b7c58d80
20 changed files with 596 additions and 10000 deletions

View file

@ -20,7 +20,7 @@ import {
TRANSITION_REVIEW_2_BY_PROVIDER,
TX_TRANSITION_ACTOR_CUSTOMER,
TX_TRANSITION_ACTOR_PROVIDER,
} from '../../util/types';
} from '../../util/transaction';
import ActivityFeed from './ActivityFeed';
const noop = () => null;

View file

@ -21,8 +21,8 @@ import {
TX_TRANSITION_ACTOR_CUSTOMER,
TX_TRANSITION_ACTOR_PROVIDER,
areReviewsCompleted,
propTypes,
} from '../../util/types';
} from '../../util/transaction';
import { propTypes } from '../../util/types';
import * as log from '../../util/log';
import css from './ActivityFeed.css';

View file

@ -1,9 +1,6 @@
import Decimal from 'decimal.js';
import { types as sdkTypes } from '../../util/sdkLoader';
import {
LINE_ITEM_DAY,
LINE_ITEM_NIGHT,
LINE_ITEM_UNITS,
TRANSITION_ACCEPT,
TRANSITION_CANCEL,
TRANSITION_COMPLETE,
@ -11,7 +8,8 @@ import {
TRANSITION_EXPIRE,
TRANSITION_REQUEST,
TX_TRANSITION_ACTOR_CUSTOMER,
} from '../../util/types';
} from '../../util/transaction';
import { LINE_ITEM_DAY, LINE_ITEM_NIGHT, LINE_ITEM_UNITS } from '../../util/types';
import config from '../../config';
import BookingBreakdown from './BookingBreakdown';

View file

@ -4,11 +4,11 @@ import { fakeIntl, createBooking } from '../../util/test-data';
import { renderDeep } from '../../util/test-helpers';
import { types as sdkTypes } from '../../util/sdkLoader';
import {
LINE_ITEM_NIGHT,
TRANSITION_CANCEL,
TRANSITION_REQUEST,
TX_TRANSITION_ACTOR_CUSTOMER,
} from '../../util/types';
} from '../../util/transaction';
import { LINE_ITEM_NIGHT } from '../../util/types';
import { BookingBreakdownComponent } from './BookingBreakdown';
const { UUID, Money } = sdkTypes;

View file

@ -2,7 +2,8 @@ import React from 'react';
import { bool } from 'prop-types';
import { FormattedMessage, intlShape } from 'react-intl';
import { formatMoney } from '../../util/currency';
import { txIsCanceled, txIsCompleted, txIsDeclinedOrExpired, propTypes } from '../../util/types';
import { txIsCanceled, txIsCompleted, txIsDeclinedOrExpired } from '../../util/transaction';
import { propTypes } from '../../util/types';
import css from './BookingBreakdown.css';

View file

@ -19,8 +19,8 @@ import {
TRANSITION_ENQUIRE,
TRANSITION_EXPIRE,
TRANSITION_REQUEST,
} from '../../util/types';
import { BreakdownMaybe } from './TransactionPanel.helpers';
} from '../../util/transaction';
import BreakdownMaybe from './BreakdownMaybe';
import { TransactionPanelComponent } from './TransactionPanel';
const noop = () => null;

View file

@ -2,7 +2,7 @@ import pick from 'lodash/pick';
import config from '../../config';
import { denormalisedResponseEntities } from '../../util/data';
import { storableError } from '../../util/errors';
import { TRANSITION_REQUEST, TRANSITION_REQUEST_AFTER_ENQUIRY } from '../../util/types';
import { TRANSITION_REQUEST, TRANSITION_REQUEST_AFTER_ENQUIRY } from '../../util/transaction';
import * as log from '../../util/log';
import { fetchCurrentUserHasOrdersSuccess } from '../../ducks/user.duck';

View file

@ -7,7 +7,7 @@
import moment from 'moment';
import reduce from 'lodash/reduce';
import { types as sdkTypes } from '../../util/sdkLoader';
import { TRANSITION_ENQUIRE } from '../../util/types';
import { TRANSITION_ENQUIRE } from '../../util/transaction';
const { UUID, Money } = sdkTypes;

View file

@ -6,8 +6,6 @@ import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import moment from 'moment';
import classNames from 'classnames';
import {
LINE_ITEM_DAY,
LINE_ITEM_UNITS,
txHasFirstReview,
txIsAccepted,
txIsCanceled,
@ -16,8 +14,8 @@ import {
txIsEnquired,
txIsRequested,
txIsReviewed,
propTypes,
} from '../../util/types';
} from '../../util/transaction';
import { LINE_ITEM_DAY, LINE_ITEM_UNITS, propTypes } from '../../util/types';
import { formatMoney } from '../../util/currency';
import { ensureCurrentUser, userDisplayName } from '../../util/data';
import { dateFromAPIToLocalNoon, daysBetween } from '../../util/dates';

View file

@ -10,7 +10,8 @@ import {
} from '../../util/test-data';
import { InboxPageComponent, InboxItem } from './InboxPage';
import routeConfiguration from '../../routeConfiguration';
import { LINE_ITEM_NIGHT, TRANSITION_REQUEST } from '../../util/types';
import { TRANSITION_REQUEST } from '../../util/transaction';
import { LINE_ITEM_NIGHT } from '../../util/types';
const noop = () => null;

View file

@ -5,7 +5,7 @@ import { types as sdkTypes } from '../../util/sdkLoader';
import { storableError } from '../../util/errors';
import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck';
import { denormalisedResponseEntities } from '../../util/data';
import { TRANSITION_ENQUIRE } from '../../util/types';
import { TRANSITION_ENQUIRE } from '../../util/transaction';
import {
LISTING_PAGE_DRAFT_VARIANT,
LISTING_PAGE_PENDING_APPROVAL_VARIANT,

View file

@ -13,7 +13,7 @@ import {
TRANSITION_REVIEW_1_BY_PROVIDER,
TRANSITION_REVIEW_2_BY_CUSTOMER,
TRANSITION_REVIEW_2_BY_PROVIDER,
} from '../../util/types';
} from '../../util/transaction';
import * as log from '../../util/log';
import {
updatedEntities,

View file

@ -8,7 +8,7 @@ import {
fakeIntl,
} from '../../util/test-data';
import { renderShallow } from '../../util/test-helpers';
import { TRANSITION_REQUEST } from '../../util/types';
import { TRANSITION_REQUEST } from '../../util/transaction';
import { TransactionPageComponent } from './TransactionPage';
const noop = () => null;

View file

@ -3,11 +3,8 @@ import isUndefined from 'lodash/isUndefined';
import config from '../config';
import { denormalisedResponseEntities, ensureOwnListing } from '../util/data';
import { storableError } from '../util/errors';
import {
LISTING_STATE_DRAFT,
TRANSITION_REQUEST,
TRANSITION_REQUEST_AFTER_ENQUIRY,
} from '../util/types';
import { TRANSITION_REQUEST, TRANSITION_REQUEST_AFTER_ENQUIRY } from '../util/transaction';
import { LISTING_STATE_DRAFT } from '../util/types';
import * as log from '../util/log';
import { authInfo } from './Auth.duck';

View file

@ -4,7 +4,8 @@ import Decimal from 'decimal.js';
import { types as sdkTypes } from '../../util/sdkLoader';
import { renderShallow, renderDeep } from '../../util/test-helpers';
import { fakeIntl } from '../../util/test-data';
import { LINE_ITEM_NIGHT, TRANSITION_REQUEST } from '../../util/types';
import { TRANSITION_REQUEST } from '../../util/transaction';
import { LINE_ITEM_NIGHT } from '../../util/types';
import { dateFromAPIToLocalNoon } from '../../util/dates';
import { BookingBreakdown } from '../../components';
import { BookingDatesFormComponent } from './BookingDatesForm';

View file

@ -30,13 +30,8 @@ import moment from 'moment';
import Decimal from 'decimal.js';
import { types as sdkTypes } from '../../util/sdkLoader';
import { dateFromLocalToAPI, nightsBetween, daysBetween } from '../../util/dates';
import {
LINE_ITEM_DAY,
LINE_ITEM_NIGHT,
LINE_ITEM_UNITS,
TRANSITION_REQUEST,
TX_TRANSITION_ACTOR_CUSTOMER,
} from '../../util/types';
import { TRANSITION_REQUEST, TX_TRANSITION_ACTOR_CUSTOMER } from '../../util/transaction';
import { LINE_ITEM_DAY, LINE_ITEM_NIGHT, LINE_ITEM_UNITS } from '../../util/types';
import { unitDivisor, convertMoneyToNumber, convertUnitToSubUnit } from '../../util/currency';
import { BookingBreakdown } from '../../components';

View file

@ -7,9 +7,8 @@ import {
TRANSITION_REQUEST,
TX_TRANSITION_ACTOR_CUSTOMER,
TX_TRANSITION_ACTOR_PROVIDER,
LISTING_STATE_PUBLISHED,
TIME_SLOT_DAY,
} from '../util/types';
} from '../util/transaction';
import { LISTING_STATE_PUBLISHED, TIME_SLOT_DAY } from '../util/types';
const { UUID, LatLng, Money } = sdkTypes;

119
src/util/transaction.js Normal file
View file

@ -0,0 +1,119 @@
import { ensureTransaction } from './data';
// When a customer makes a booking to a listing, a transaction is
// created with the initial request transition.
export const TRANSITION_REQUEST = 'transition/request';
// A customer can also initiate a transaction with an enquiry, and
// then transition that with a request.
export const TRANSITION_ENQUIRE = 'transition/enquire';
export const TRANSITION_REQUEST_AFTER_ENQUIRY = 'transition/request-after-enquiry';
// When the provider accepts or declines a transaction from the
// SalePage, it is transitioned with the accept or decline transition.
export const TRANSITION_ACCEPT = 'transition/accept';
export const TRANSITION_DECLINE = 'transition/decline';
// The backend automatically expire the transaction.
export const TRANSITION_EXPIRE = 'transition/expire';
// Admin can also cancel the transition.
export const TRANSITION_CANCEL = 'transition/cancel';
// The backend will mark the transaction completed.
export const TRANSITION_COMPLETE = 'transition/complete';
// Reviews are given through transaction transitions. Review 1 can be
// by provider or customer, and review 2 will be the other party of
// the transaction.
export const TRANSITION_REVIEW_1_BY_PROVIDER = 'transition/review-1-by-provider';
export const TRANSITION_REVIEW_2_BY_PROVIDER = 'transition/review-2-by-provider';
export const TRANSITION_REVIEW_1_BY_CUSTOMER = 'transition/review-1-by-customer';
export const TRANSITION_REVIEW_2_BY_CUSTOMER = 'transition/review-2-by-customer';
export const TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD = 'transition/expire-customer-review-period';
export const TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD = 'transition/expire-provider-review-period';
export const TRANSITION_EXPIRE_REVIEW_PERIOD = 'transition/expire-review-period';
export const TRANSITIONS = [
TRANSITION_ACCEPT,
TRANSITION_CANCEL,
TRANSITION_COMPLETE,
TRANSITION_DECLINE,
TRANSITION_ENQUIRE,
TRANSITION_EXPIRE,
TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD,
TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD,
TRANSITION_EXPIRE_REVIEW_PERIOD,
TRANSITION_REQUEST,
TRANSITION_REQUEST_AFTER_ENQUIRY,
TRANSITION_REVIEW_1_BY_CUSTOMER,
TRANSITION_REVIEW_1_BY_PROVIDER,
TRANSITION_REVIEW_2_BY_CUSTOMER,
TRANSITION_REVIEW_2_BY_PROVIDER,
];
const txLastTransition = tx => ensureTransaction(tx).attributes.lastTransition;
export const txIsEnquired = tx => txLastTransition(tx) === TRANSITION_ENQUIRE;
export const txIsRequested = tx => {
const transition = txLastTransition(tx);
return transition === TRANSITION_REQUEST || transition === TRANSITION_REQUEST_AFTER_ENQUIRY;
};
export const txIsAccepted = tx => txLastTransition(tx) === TRANSITION_ACCEPT;
export const txIsDeclined = tx => txLastTransition(tx) === TRANSITION_DECLINE;
export const txIsExpired = tx => txLastTransition(tx) === TRANSITION_EXPIRE;
export const txIsDeclinedOrExpired = tx => txIsDeclined(tx) || txIsExpired(tx);
export const txIsCanceled = tx => txLastTransition(tx) === TRANSITION_CANCEL;
export const txIsCompleted = tx => txLastTransition(tx) === TRANSITION_COMPLETE;
const firstReviewTransitions = [TRANSITION_REVIEW_1_BY_CUSTOMER, TRANSITION_REVIEW_1_BY_PROVIDER];
export const txHasFirstReview = tx => firstReviewTransitions.includes(txLastTransition(tx));
export const txIsReviewed = tx => areReviewsCompleted(txLastTransition(tx));
// Check if tx transition is followed by a state where
// reviews are completed
export const areReviewsCompleted = transition => {
return [
TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD,
TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD,
TRANSITION_EXPIRE_REVIEW_PERIOD,
TRANSITION_REVIEW_2_BY_CUSTOMER,
TRANSITION_REVIEW_2_BY_PROVIDER,
].includes(transition);
};
export const txHasBeenAccepted = tx => {
const transition = txLastTransition(tx);
return [
TRANSITION_ACCEPT,
TRANSITION_REVIEW_1_BY_CUSTOMER,
TRANSITION_REVIEW_1_BY_PROVIDER,
TRANSITION_REVIEW_2_BY_CUSTOMER,
TRANSITION_REVIEW_2_BY_PROVIDER,
TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD,
TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD,
TRANSITION_EXPIRE_REVIEW_PERIOD,
TRANSITION_COMPLETE,
].includes(transition);
};
// Roles of actors that perform transaction transitions
export const TX_TRANSITION_ACTOR_CUSTOMER = 'customer';
export const TX_TRANSITION_ACTOR_PROVIDER = 'provider';
export const TX_TRANSITION_ACTOR_SYSTEM = 'system';
export const TX_TRANSITION_ACTOR_OPERATOR = 'operator';
export const TX_TRANSITION_ACTORS = [
TX_TRANSITION_ACTOR_CUSTOMER,
TX_TRANSITION_ACTOR_PROVIDER,
TX_TRANSITION_ACTOR_SYSTEM,
TX_TRANSITION_ACTOR_OPERATOR,
];

View file

@ -32,7 +32,7 @@ import {
} from 'prop-types';
import Decimal from 'decimal.js';
import { types as sdkTypes } from './sdkLoader';
import { ensureTransaction } from './data';
import { TRANSITIONS, TX_TRANSITION_ACTORS } from './transaction';
const { UUID, LatLng, LatLngBounds, Money } = sdkTypes;
@ -231,131 +231,12 @@ propTypes.availabilityException = shape({
}),
});
// When a customer makes a booking to a listing, a transaction is
// created with the initial request transition.
export const TRANSITION_REQUEST = 'transition/request';
// A customer can also initiate a transaction with an enquiry, and
// then transition that with a request.
export const TRANSITION_ENQUIRE = 'transition/enquire';
export const TRANSITION_REQUEST_AFTER_ENQUIRY = 'transition/request-after-enquiry';
// When the provider accepts or declines a transaction from the
// SalePage, it is transitioned with the accept or decline transition.
export const TRANSITION_ACCEPT = 'transition/accept';
export const TRANSITION_DECLINE = 'transition/decline';
// The backend automatically expire the transaction.
export const TRANSITION_EXPIRE = 'transition/expire';
// Admin can also cancel the transition.
export const TRANSITION_CANCEL = 'transition/cancel';
// The backend will mark the transaction completed.
export const TRANSITION_COMPLETE = 'transition/complete';
// Reviews are given through transaction transitions. Review 1 can be
// by provider or customer, and review 2 will be the other party of
// the transaction.
export const TRANSITION_REVIEW_1_BY_PROVIDER = 'transition/review-1-by-provider';
export const TRANSITION_REVIEW_2_BY_PROVIDER = 'transition/review-2-by-provider';
export const TRANSITION_REVIEW_1_BY_CUSTOMER = 'transition/review-1-by-customer';
export const TRANSITION_REVIEW_2_BY_CUSTOMER = 'transition/review-2-by-customer';
export const TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD = 'transition/expire-customer-review-period';
export const TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD = 'transition/expire-provider-review-period';
export const TRANSITION_EXPIRE_REVIEW_PERIOD = 'transition/expire-review-period';
export const TRANSITIONS = [
TRANSITION_ACCEPT,
TRANSITION_CANCEL,
TRANSITION_COMPLETE,
TRANSITION_DECLINE,
TRANSITION_ENQUIRE,
TRANSITION_EXPIRE,
TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD,
TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD,
TRANSITION_EXPIRE_REVIEW_PERIOD,
TRANSITION_REQUEST,
TRANSITION_REQUEST_AFTER_ENQUIRY,
TRANSITION_REVIEW_1_BY_CUSTOMER,
TRANSITION_REVIEW_1_BY_PROVIDER,
TRANSITION_REVIEW_2_BY_CUSTOMER,
TRANSITION_REVIEW_2_BY_PROVIDER,
];
// Roles of actors that perform transaction transitions
export const TX_TRANSITION_ACTOR_CUSTOMER = 'customer';
export const TX_TRANSITION_ACTOR_PROVIDER = 'provider';
export const TX_TRANSITION_ACTOR_SYSTEM = 'system';
export const TX_TRANSITION_ACTOR_OPERATOR = 'operator';
export const TX_TRANSITION_ACTORS = [
TX_TRANSITION_ACTOR_CUSTOMER,
TX_TRANSITION_ACTOR_PROVIDER,
TX_TRANSITION_ACTOR_SYSTEM,
TX_TRANSITION_ACTOR_OPERATOR,
];
const txLastTransition = tx => ensureTransaction(tx).attributes.lastTransition;
export const txIsEnquired = tx => txLastTransition(tx) === TRANSITION_ENQUIRE;
export const txIsRequested = tx => {
const transition = txLastTransition(tx);
return transition === TRANSITION_REQUEST || transition === TRANSITION_REQUEST_AFTER_ENQUIRY;
};
export const txIsAccepted = tx => txLastTransition(tx) === TRANSITION_ACCEPT;
export const txIsDeclined = tx => txLastTransition(tx) === TRANSITION_DECLINE;
export const txIsExpired = tx => txLastTransition(tx) === TRANSITION_EXPIRE;
export const txIsDeclinedOrExpired = tx => txIsDeclined(tx) || txIsExpired(tx);
export const txIsCanceled = tx => txLastTransition(tx) === TRANSITION_CANCEL;
export const txIsCompleted = tx => txLastTransition(tx) === TRANSITION_COMPLETE;
export const txHasFirstReview = tx => firstReviewTransitions.includes(txLastTransition(tx));
export const txIsReviewed = tx => areReviewsCompleted(txLastTransition(tx));
propTypes.transition = shape({
createdAt: instanceOf(Date).isRequired,
by: oneOf(TX_TRANSITION_ACTORS).isRequired,
transition: oneOf(TRANSITIONS).isRequired,
});
const firstReviewTransitions = [TRANSITION_REVIEW_1_BY_CUSTOMER, TRANSITION_REVIEW_1_BY_PROVIDER];
// Check if tx transition is followed by a state where
// reviews are completed
export const areReviewsCompleted = transition => {
return [
TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD,
TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD,
TRANSITION_EXPIRE_REVIEW_PERIOD,
TRANSITION_REVIEW_2_BY_CUSTOMER,
TRANSITION_REVIEW_2_BY_PROVIDER,
].includes(transition);
};
export const txHasBeenAccepted = tx => {
const transition = txLastTransition(tx);
return [
TRANSITION_ACCEPT,
TRANSITION_REVIEW_1_BY_CUSTOMER,
TRANSITION_REVIEW_1_BY_PROVIDER,
TRANSITION_REVIEW_2_BY_CUSTOMER,
TRANSITION_REVIEW_2_BY_PROVIDER,
TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD,
TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD,
TRANSITION_EXPIRE_REVIEW_PERIOD,
TRANSITION_COMPLETE,
].includes(transition);
};
// Possible amount of stars in a review
export const REVIEW_RATINGS = [1, 2, 3, 4, 5];