From 804d2672cdd944c4694ffbe83a1345cb17d0d3ac Mon Sep 17 00:00:00 2001 From: Mikko Koski Date: Thu, 29 Jun 2017 13:50:11 +0300 Subject: [PATCH 01/11] Use payinTotal and payoutTotal instead of total and commission --- .../OrderDetailsPanel/OrderDetailsPanel.js | 2 +- .../SaleDetailsPanel/SaleDetailsPanel.js | 22 +++++++++---------- src/util/propTypes.js | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/components/OrderDetailsPanel/OrderDetailsPanel.js b/src/components/OrderDetailsPanel/OrderDetailsPanel.js index ca821776..34c5b315 100644 --- a/src/components/OrderDetailsPanel/OrderDetailsPanel.js +++ b/src/components/OrderDetailsPanel/OrderDetailsPanel.js @@ -15,7 +15,7 @@ const breakdown = transaction => { const bookingStart = booking.attributes.start; const bookingEnd = booking.attributes.end; const unitPrice = listing.attributes.price; - const totalPrice = tx.attributes.total; + const totalPrice = tx.attributes.payinTotal; if (!bookingStart || !bookingEnd || !unitPrice || !totalPrice) { return null; diff --git a/src/components/SaleDetailsPanel/SaleDetailsPanel.js b/src/components/SaleDetailsPanel/SaleDetailsPanel.js index eac2da77..6a6968d4 100644 --- a/src/components/SaleDetailsPanel/SaleDetailsPanel.js +++ b/src/components/SaleDetailsPanel/SaleDetailsPanel.js @@ -15,19 +15,19 @@ import css from './SaleDetailsPanel.css'; // TODO: This is a temporary function to calculate the booking // price. This should be removed when the API supports dry-runs and we // can take the total price from the transaction itself. -const estimatedProviderTotalPrice = (customerTotalPrice, commission) => { +const estimatedCommission = (customerTotalPrice, providerTotalPrice) => { const { subUnitDivisor, currency } = config.currencyConfig; - if (customerTotalPrice.currency !== currency || commission.currency !== currency) { + if (customerTotalPrice.currency !== currency || providerTotalPrice.currency !== currency) { throw new Error('Transaction total or commission currency does not match marketplace currency'); } const numericCustomerTotalPrice = convertMoneyToNumber(customerTotalPrice, subUnitDivisor); - const numericCommission = convertMoneyToNumber(commission, subUnitDivisor); - const numericTotalPrice = new Decimal(numericCustomerTotalPrice) - .minus(numericCommission) + const numericProviderTotalPrice = convertMoneyToNumber(providerTotalPrice, subUnitDivisor); + const numericCommission = new Decimal(numericProviderTotalPrice) + .minus(numericCustomerTotalPrice) .toNumber(); - return new types.Money(convertUnitToSubUnit(numericTotalPrice, subUnitDivisor), currency); + return new types.Money(convertUnitToSubUnit(numericCommission, subUnitDivisor), currency); }; const breakdown = transaction => { @@ -37,14 +37,14 @@ const breakdown = transaction => { const bookingStart = booking.attributes.start; const bookingEnd = booking.attributes.end; const unitPrice = listing.attributes.price; - const customerTotalPrice = tx.attributes.total; - const commission = tx.attributes.commission; + const customerTotalPrice = tx.attributes.payinTotal; + const providerTotalPrice = tx.attributes.payoutTotal; - if (!bookingStart || !bookingEnd || !unitPrice || !customerTotalPrice || !commission) { + if (!bookingStart || !bookingEnd || !unitPrice || !customerTotalPrice || !providerTotalPrice) { return null; } - const totalPrice = estimatedProviderTotalPrice(customerTotalPrice, commission); + const commission = estimatedCommission(customerTotalPrice, providerTotalPrice); return ( { bookingStart={bookingStart} bookingEnd={bookingEnd} unitPrice={unitPrice} - totalPrice={totalPrice} + totalPrice={providerTotalPrice} commission={commission} /> ); diff --git a/src/util/propTypes.js b/src/util/propTypes.js index bedfa103..97e275e6 100644 --- a/src/util/propTypes.js +++ b/src/util/propTypes.js @@ -147,12 +147,12 @@ export const transaction = shape({ id: uuid.isRequired, type: value('transaction').isRequired, attributes: shape({ - commission: money.isRequired, createdAt: instanceOf(Date).isRequired, lastTransitionedAt: instanceOf(Date).isRequired, lastTransition: string, state: oneOf(TX_STATES).isRequired, - total: money.isRequired, + payinTotal: money.isRequired, + payoutTotal: money.isRequired, }), booking, listing, From 4364a4a7b25db58e6f20ae9577e466a9f1292bc5 Mon Sep 17 00:00:00 2001 From: Mikko Koski Date: Thu, 29 Jun 2017 17:52:07 +0300 Subject: [PATCH 02/11] Update SDK --- package.json | 2 +- yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index bcf33cc6..d173c9fa 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "redux-thunk": "^2.2.0", "sanitize.css": "^5.0.0", "sharetribe-scripts": "0.9.2", - "sharetribe-sdk": "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#a3d2bfcc64e0b91c6626b959c8395fbda39fd0d8", + "sharetribe-sdk": "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#a086f37c765cf5b6034bc5f4788788237485c863", "source-map-support": "^0.4.14", "url": "^0.11.0" }, diff --git a/yarn.lock b/yarn.lock index bb4a7398..0a3ba2fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6008,9 +6008,9 @@ sharetribe-scripts@0.9.2: optionalDependencies: fsevents "1.0.17" -"sharetribe-sdk@git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#a3d2bfcc64e0b91c6626b959c8395fbda39fd0d8": +"sharetribe-sdk@git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#a086f37c765cf5b6034bc5f4788788237485c863": version "0.0.1" - resolved "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#a3d2bfcc64e0b91c6626b959c8395fbda39fd0d8" + resolved "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#a086f37c765cf5b6034bc5f4788788237485c863" dependencies: axios "^0.15.3" js-cookie "^2.1.3" From f265c72a551a37f71428cda8ca0eae4c9184b6a2 Mon Sep 17 00:00:00 2001 From: Mikko Koski Date: Thu, 29 Jun 2017 14:25:30 +0300 Subject: [PATCH 03/11] Use line items to show price breakdown --- server/index.js | 9 ++++ .../BookingBreakdown/BookingBreakdown.js | 44 +++++++++++++------ .../OrderDetailsPanel/OrderDetailsPanel.js | 14 +++--- .../SaleDetailsPanel/SaleDetailsPanel.js | 40 ++++------------- src/index.js | 16 ++++++- 5 files changed, 71 insertions(+), 52 deletions(-) diff --git a/server/index.js b/server/index.js index 5618d8ad..a09e62ff 100644 --- a/server/index.js +++ b/server/index.js @@ -24,6 +24,7 @@ const enforceSsl = require('express-enforces-ssl'); const path = require('path'); const qs = require('qs'); const sharetribeSdk = require('sharetribe-sdk'); +const Decimal = require('decimal.js'); const auth = require('./auth'); const renderer = require('./renderer'); const dataLoader = require('./dataLoader'); @@ -89,6 +90,14 @@ app.get('*', (req, res) => { req, res, }), + typeHandlers: [ + { + type: sharetribeSdk.types.BigDecimal, + customType: Decimal, + writer: v => new sharetribeSdk.types.BigDecimal(v.toString()), + reader: v => new Decimal(v.value), + }, + ], }); dataLoader diff --git a/src/components/BookingBreakdown/BookingBreakdown.js b/src/components/BookingBreakdown/BookingBreakdown.js index a6e0da1d..0a3bf9ca 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.js +++ b/src/components/BookingBreakdown/BookingBreakdown.js @@ -2,6 +2,7 @@ * This component will show the booking info and calculated total price. * I.e. dates and other details related to payment decision in receipt format. */ +import _ from 'lodash'; import React, { PropTypes } from 'react'; import { FormattedMessage, intlShape, injectIntl } from 'react-intl'; import Decimal from 'decimal.js'; @@ -9,7 +10,6 @@ import classNames from 'classnames'; import config from '../../config'; import { convertMoneyToNumber } from '../../util/currency'; import * as propTypes from '../../util/propTypes'; -import { nightsBetween } from '../../util/dates'; import css from './BookingBreakdown.css'; @@ -19,9 +19,10 @@ export const BookingBreakdownComponent = props => { className, bookingStart, bookingEnd, - unitPrice, - commission, - totalPrice, + payinTotal, + payoutTotal, + lineItems, + userRole, intl, } = props; @@ -50,7 +51,13 @@ export const BookingBreakdownComponent = props => { /> ); - const nightCount = nightsBetween(bookingStart, bookingEnd); + const nightPurchase = _.find(lineItems, item => item.code === 'line-item.purchase/night'); + const providerCommission = _.find( + lineItems, + item => item.code === 'line-item.commission/provider' + ); + + const nightCount = nightPurchase.quantity.toFixed(); const nightCountMessage = ( ); @@ -58,10 +65,11 @@ export const BookingBreakdownComponent = props => { const currencyConfig = config.currencyConfig; const subUnitDivisor = currencyConfig.subUnitDivisor; - const unitPriceAsNumber = convertMoneyToNumber(unitPrice, subUnitDivisor); + const unitPriceAsNumber = convertMoneyToNumber(nightPurchase.unitPrice, subUnitDivisor); const formattedUnitPrice = intl.formatNumber(unitPriceAsNumber, currencyConfig); // If commission is passed it will be shown as a fee already reduces from the total price + const commission = providerCommission.lineTotal; const commissionAsNumber = commission ? convertMoneyToNumber(commission, subUnitDivisor) : 0; const formattedCommission = commission ? intl.formatNumber(new Decimal(commissionAsNumber).negated().toNumber(), currencyConfig) @@ -76,7 +84,10 @@ export const BookingBreakdownComponent = props => { ); - const totalPriceAsNumber = convertMoneyToNumber(totalPrice, subUnitDivisor); + const totalPriceAsNumber = convertMoneyToNumber( + userRole === 'customer' ? payinTotal : payoutTotal, + subUnitDivisor + ); const formattedTotalPrice = totalPriceAsNumber ? intl.formatNumber(totalPriceAsNumber, currencyConfig) : null; @@ -95,7 +106,7 @@ export const BookingBreakdownComponent = props => { {nightCountMessage} - {commission ? commissionInfo : null} + {userRole === 'provider' ? commissionInfo : null}
@@ -115,7 +126,14 @@ BookingBreakdownComponent.defaultProps = { commission: null, }; -const { string, instanceOf } = PropTypes; +const { string, instanceOf, arrayOf, oneOf, shape } = PropTypes; + +const lineItem = shape({ + code: string.isRequired, + quantity: instanceOf(Decimal), + unitPrice: propTypes.money, + lineTotal: propTypes.money, +}); BookingBreakdownComponent.propTypes = { rootClassName: string, @@ -123,10 +141,10 @@ BookingBreakdownComponent.propTypes = { bookingStart: instanceOf(Date).isRequired, bookingEnd: instanceOf(Date).isRequired, - - unitPrice: propTypes.money.isRequired, - totalPrice: propTypes.money.isRequired, - commission: propTypes.money, + lineItems: arrayOf(lineItem).isRequired, + userRole: oneOf(['customer', 'provider']).isRequired, + payinTotal: propTypes.money.isRequired, + payoutTotal: propTypes.money.isRequired, // from injectIntl intl: intlShape.isRequired, diff --git a/src/components/OrderDetailsPanel/OrderDetailsPanel.js b/src/components/OrderDetailsPanel/OrderDetailsPanel.js index 34c5b315..4f0006c5 100644 --- a/src/components/OrderDetailsPanel/OrderDetailsPanel.js +++ b/src/components/OrderDetailsPanel/OrderDetailsPanel.js @@ -10,14 +10,14 @@ import css from './OrderDetailsPanel.css'; const breakdown = transaction => { const tx = ensureTransaction(transaction); - const listing = ensureListing(tx.listing); const booking = ensureBooking(tx.booking); const bookingStart = booking.attributes.start; const bookingEnd = booking.attributes.end; - const unitPrice = listing.attributes.price; - const totalPrice = tx.attributes.payinTotal; + const payinTotal = tx.attributes.payinTotal; + const payoutTotal = tx.attributes.payoutTotal; + const lineItems = tx.attributes.lineItems; - if (!bookingStart || !bookingEnd || !unitPrice || !totalPrice) { + if (!bookingStart || !bookingEnd || !payinTotal || !payoutTotal || !lineItems) { return null; } return ( @@ -25,8 +25,10 @@ const breakdown = transaction => { className={css.receipt} bookingStart={bookingStart} bookingEnd={bookingEnd} - unitPrice={unitPrice} - totalPrice={totalPrice} + payinTotal={payinTotal} + payoutTotal={payoutTotal} + lineItems={lineItems} + userRole="customer" /> ); }; diff --git a/src/components/SaleDetailsPanel/SaleDetailsPanel.js b/src/components/SaleDetailsPanel/SaleDetailsPanel.js index 6a6968d4..8c0a740d 100644 --- a/src/components/SaleDetailsPanel/SaleDetailsPanel.js +++ b/src/components/SaleDetailsPanel/SaleDetailsPanel.js @@ -1,59 +1,35 @@ import React, { PropTypes } from 'react'; import { FormattedDate, FormattedMessage } from 'react-intl'; -import Decimal from 'decimal.js'; import classNames from 'classnames'; import * as propTypes from '../../util/propTypes'; -import { types } from '../../util/sdkLoader'; import { createSlug } from '../../util/urlHelpers'; import { ensureListing, ensureTransaction, ensureBooking, ensureUser } from '../../util/data'; -import { convertMoneyToNumber, convertUnitToSubUnit } from '../../util/currency'; -import config from '../../config'; import { Avatar, BookingBreakdown, NamedLink } from '../../components'; import css from './SaleDetailsPanel.css'; -// TODO: This is a temporary function to calculate the booking -// price. This should be removed when the API supports dry-runs and we -// can take the total price from the transaction itself. -const estimatedCommission = (customerTotalPrice, providerTotalPrice) => { - const { subUnitDivisor, currency } = config.currencyConfig; - if (customerTotalPrice.currency !== currency || providerTotalPrice.currency !== currency) { - throw new Error('Transaction total or commission currency does not match marketplace currency'); - } - - const numericCustomerTotalPrice = convertMoneyToNumber(customerTotalPrice, subUnitDivisor); - const numericProviderTotalPrice = convertMoneyToNumber(providerTotalPrice, subUnitDivisor); - const numericCommission = new Decimal(numericProviderTotalPrice) - .minus(numericCustomerTotalPrice) - .toNumber(); - - return new types.Money(convertUnitToSubUnit(numericCommission, subUnitDivisor), currency); -}; - const breakdown = transaction => { const tx = ensureTransaction(transaction); - const listing = ensureListing(tx.listing); const booking = ensureBooking(tx.booking); const bookingStart = booking.attributes.start; const bookingEnd = booking.attributes.end; - const unitPrice = listing.attributes.price; - const customerTotalPrice = tx.attributes.payinTotal; - const providerTotalPrice = tx.attributes.payoutTotal; + const payinTotal = tx.attributes.payinTotal; + const payoutTotal = tx.attributes.payoutTotal; + const lineItems = tx.attributes.lineItems; - if (!bookingStart || !bookingEnd || !unitPrice || !customerTotalPrice || !providerTotalPrice) { + if (!bookingStart || !bookingEnd || !payinTotal || !payoutTotal || !lineItems) { return null; } - const commission = estimatedCommission(customerTotalPrice, providerTotalPrice); - return ( ); }; diff --git a/src/index.js b/src/index.js index a82c6210..b4fc1b9a 100644 --- a/src/index.js +++ b/src/index.js @@ -13,6 +13,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import Decimal from 'decimal.js'; import { createInstance, types } from './util/sdkLoader'; import { ClientApp, renderApp } from './app'; import configureStore from './store'; @@ -25,6 +26,8 @@ import routeConfiguration from './routesConfiguration'; import './marketplace.css'; +const { BigDecimal } = types; + const render = store => { // If the server already loaded the auth information, render the app // immediately. Otherwise wait for the flag to be loaded and render @@ -54,7 +57,18 @@ if (typeof window !== 'undefined') { // eslint-disable-next-line no-underscore-dangle const preloadedState = window.__PRELOADED_STATE__ || '{}'; const initialState = JSON.parse(preloadedState, types.reviver); - const sdk = createInstance({ clientId: config.sdk.clientId, baseUrl: config.sdk.baseUrl }); + const sdk = createInstance({ + clientId: config.sdk.clientId, + baseUrl: config.sdk.baseUrl, + typeHandlers: [ + { + type: BigDecimal, + customType: Decimal, + writer: v => new BigDecimal(v.toString()), + reader: v => new Decimal(v.value), + }, + ], + }); const store = configureStore(sdk, initialState); setupStripe(); From 227aef9cf5b66020d6d419725b98afeabffeb829 Mon Sep 17 00:00:00 2001 From: Mikko Koski Date: Fri, 30 Jun 2017 09:05:47 +0300 Subject: [PATCH 04/11] Make pretransaction breakdown to use line items --- .../BookingBreakdown/BookingBreakdown.js | 28 +++++++++++-------- .../BookingDatesForm/BookingDatesForm.js | 17 ++++++++--- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/components/BookingBreakdown/BookingBreakdown.js b/src/components/BookingBreakdown/BookingBreakdown.js index 0a3bf9ca..d4561895 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.js +++ b/src/components/BookingBreakdown/BookingBreakdown.js @@ -69,20 +69,23 @@ export const BookingBreakdownComponent = props => { const formattedUnitPrice = intl.formatNumber(unitPriceAsNumber, currencyConfig); // If commission is passed it will be shown as a fee already reduces from the total price - const commission = providerCommission.lineTotal; - const commissionAsNumber = commission ? convertMoneyToNumber(commission, subUnitDivisor) : 0; - const formattedCommission = commission - ? intl.formatNumber(new Decimal(commissionAsNumber).negated().toNumber(), currencyConfig) - : null; + let commissionInfo = null; - const commissionInfo = ( -
+ if (userRole === "provider") { + const commission = providerCommission.lineTotal; + const commissionAsNumber = commission ? convertMoneyToNumber(commission, subUnitDivisor) : 0; + const formattedCommission = commission + ? intl.formatNumber(new Decimal(commissionAsNumber).negated().toNumber(), currencyConfig) + : null; + + commissionInfo = ( +
{formattedCommission}
- ); + ); const totalPriceAsNumber = convertMoneyToNumber( userRole === 'customer' ? payinTotal : payoutTotal, @@ -106,7 +109,7 @@ export const BookingBreakdownComponent = props => { {nightCountMessage}
- {userRole === 'provider' ? commissionInfo : null} + {commissionInfo}
@@ -123,7 +126,8 @@ export const BookingBreakdownComponent = props => { BookingBreakdownComponent.defaultProps = { rootClassName: null, className: null, - commission: null, + payinTotal: null, + payoutTotal: null, }; const { string, instanceOf, arrayOf, oneOf, shape } = PropTypes; @@ -143,8 +147,8 @@ BookingBreakdownComponent.propTypes = { bookingEnd: instanceOf(Date).isRequired, lineItems: arrayOf(lineItem).isRequired, userRole: oneOf(['customer', 'provider']).isRequired, - payinTotal: propTypes.money.isRequired, - payoutTotal: propTypes.money.isRequired, + payinTotal: propTypes.money, // required if userRole === customer + payoutTotal: propTypes.money, // required if userRole === provider // from injectIntl intl: intlShape.isRequired, diff --git a/src/containers/BookingDatesForm/BookingDatesForm.js b/src/containers/BookingDatesForm/BookingDatesForm.js index 48a1d614..46c65d58 100644 --- a/src/containers/BookingDatesForm/BookingDatesForm.js +++ b/src/containers/BookingDatesForm/BookingDatesForm.js @@ -18,10 +18,9 @@ import css from './BookingDatesForm.css'; // TODO: This is a temporary function to calculate the booking // price. This should be removed when the API supports dry-runs and we // can take the total price from the transaction itself. -const estimatedTotalPrice = (startDate, endDate, unitPrice) => { +const estimatedTotalPrice = (unitPrice, nightCount) => { const { subUnitDivisor } = config.currencyConfig; const numericPrice = convertMoneyToNumber(unitPrice, subUnitDivisor); - const nightCount = nightsBetween(startDate, endDate); const numericTotalPrice = new Decimal(numericPrice).times(nightCount).toNumber(); return new types.Money( convertUnitToSubUnit(numericTotalPrice, subUnitDivisor), @@ -33,14 +32,24 @@ const breakdown = (bookingStart, bookingEnd, unitPrice) => { if (!bookingStart || !bookingEnd || !unitPrice) { return null; } - const totalPrice = estimatedTotalPrice(bookingStart, bookingEnd, unitPrice); + const nightCount = nightsBetween(bookingStart, bookingEnd); + const totalPrice = estimatedTotalPrice(unitPrice, nightCount); + const lineItems = [{ + code: "line-item.purchase/night", + unitPrice: unitPrice, + quantity: new Decimal(nightCount), + lineTotal: totalPrice, + }]; + return ( ); }; From 5ac536a5aeb052643c23c671abf08f757a333cfa Mon Sep 17 00:00:00 2001 From: Mikko Koski Date: Fri, 30 Jun 2017 10:01:56 +0300 Subject: [PATCH 05/11] Update tests and test data --- .../BookingBreakdown.example.js | 66 ++++++-- .../BookingBreakdown/BookingBreakdown.js | 1 + .../BookingBreakdown/BookingBreakdown.test.js | 35 ++++- .../OrderDetailsPanel/OrderDetailsPanel.js | 4 +- .../OrderDetailsPanel.test.js | 2 +- .../OrderDetailsPanel.test.js.snap | 36 ++++- .../SaleDetailsPanel/SaleDetailsPanel.test.js | 2 +- .../SaleDetailsPanel.test.js.snap | 40 +++-- .../BookingDatesForm/BookingDatesForm.js | 15 +- .../BookingDatesForm/BookingDatesForm.test.js | 4 + .../BookingDatesForm.test.js.snap | 29 +++- .../__snapshots__/InboxPage.test.js.snap | 148 +++++++++++++++--- .../__snapshots__/OrderPage.test.js.snap | 37 ++++- .../__snapshots__/SalePage.test.js.snap | 37 ++++- src/util/test-data.js | 17 +- 15 files changed, 387 insertions(+), 86 deletions(-) diff --git a/src/components/BookingBreakdown/BookingBreakdown.example.js b/src/components/BookingBreakdown/BookingBreakdown.example.js index bcc06026..a41ffcc0 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.example.js +++ b/src/components/BookingBreakdown/BookingBreakdown.example.js @@ -1,3 +1,4 @@ +import Decimal from 'decimal.js'; import { types } from '../../util/sdkLoader'; import BookingBreakdown from './BookingBreakdown'; @@ -6,8 +7,14 @@ export const Checkout = { props: { bookingStart: new Date(Date.UTC(2017, 3, 14)), bookingEnd: new Date(Date.UTC(2017, 3, 16)), - unitPrice: new types.Money(4500, 'USD'), - totalPrice: new types.Money(9000, 'USD'), + userRole: "customer", + lineItems: [{ + code: "line-item.purchase/night", + quantity: new Decimal(2), + unitPrice: new types.Money(4500, 'USD'), + lineTotal: new types.Money(9000, 'USD'), + }], + payinTotal: new types.Money(9000, 'USD'), }, }; @@ -16,8 +23,14 @@ export const CustomerOrder = { props: { bookingStart: new Date(Date.UTC(2017, 3, 14)), bookingEnd: new Date(Date.UTC(2017, 3, 16)), - unitPrice: new types.Money(4500, 'USD'), - totalPrice: new types.Money(9000, 'USD'), + userRole: "customer", + lineItems: [{ + code: "line-item.purchase/night", + quantity: new Decimal(2), + unitPrice: new types.Money(4500, 'USD'), + lineTotal: new types.Money(9000, 'USD'), + }], + payinTotal: new types.Money(9000, 'USD'), }, }; @@ -26,9 +39,18 @@ export const ProviderSale = { props: { bookingStart: new Date(Date.UTC(2017, 3, 14)), bookingEnd: new Date(Date.UTC(2017, 3, 16)), - unitPrice: new types.Money(4500, 'USD'), - commission: new types.Money(2000, 'USD'), - totalPrice: new types.Money(7000, 'USD'), + userRole: "provider", + lineItems: [{ + code: "line-item.purchase/night", + quantity: new Decimal(2), + unitPrice: new types.Money(4500, 'USD'), + lineTotal: new types.Money(9000, 'USD'), + }, { + code: "line-item.commission/provider", + unitPrice: new types.Money(-2000, 'USD'), + lineTotal: new types.Money(-2000, 'USD'), + }], + payoutTotal: new types.Money(7000, 'USD'), }, }; @@ -37,9 +59,18 @@ export const ProviderSaleZeroCommission = { props: { bookingStart: new Date(Date.UTC(2017, 3, 14)), bookingEnd: new Date(Date.UTC(2017, 3, 16)), - unitPrice: new types.Money(4500, 'USD'), - commission: new types.Money(0, 'USD'), - totalPrice: new types.Money(7000, 'USD'), + userRole: "provider", + lineItems: [{ + code: "line-item.purchase/night", + quantity: new Decimal(2), + unitPrice: new types.Money(4500, 'USD'), + lineTotal: new types.Money(9000, 'USD'), + }, { + code: "line-item.commission/provider", + unitPrice: new types.Money(0, 'USD'), + lineTotal: new types.Money(0, 'USD'), + }], + payoutTotal: new types.Money(9000, 'USD'), }, }; @@ -48,8 +79,17 @@ export const ProviderSaleSingleNight = { props: { bookingStart: new Date(Date.UTC(2017, 3, 14)), bookingEnd: new Date(Date.UTC(2017, 3, 15)), - unitPrice: new types.Money(4500, 'USD'), - commission: new types.Money(2000, 'USD'), - totalPrice: new types.Money(2500, 'USD'), + userRole: "provider", + lineItems: [{ + code: "line-item.purchase/night", + quantity: new Decimal(1), + unitPrice: new types.Money(4500, 'USD'), + lineTotal: new types.Money(4500, 'USD'), + },{ + code: "line-item.commission/provider", + lineTotal: new types.Money(-2000, 'USD'), + unitPrice: new types.Money(-2000, 'USD'), + }], + payoutTotal: new types.Money(2500, 'USD'), }, }; diff --git a/src/components/BookingBreakdown/BookingBreakdown.js b/src/components/BookingBreakdown/BookingBreakdown.js index d4561895..1329f1ee 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.js +++ b/src/components/BookingBreakdown/BookingBreakdown.js @@ -86,6 +86,7 @@ export const BookingBreakdownComponent = props => { {formattedCommission}
); + } const totalPriceAsNumber = convertMoneyToNumber( userRole === 'customer' ? payinTotal : payoutTotal, diff --git a/src/components/BookingBreakdown/BookingBreakdown.test.js b/src/components/BookingBreakdown/BookingBreakdown.test.js index b326c566..7e5183ae 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.test.js +++ b/src/components/BookingBreakdown/BookingBreakdown.test.js @@ -1,4 +1,5 @@ import React from 'react'; +import Decimal from 'decimal.js'; import { fakeIntl } from '../../util/test-data'; import { renderDeep } from '../../util/test-helpers'; import { types } from '../../util/sdkLoader'; @@ -10,8 +11,14 @@ describe('BookingBreakdown', () => { ); @@ -23,8 +30,14 @@ describe('BookingBreakdown', () => { ); @@ -36,9 +49,19 @@ describe('BookingBreakdown', () => { ); diff --git a/src/components/OrderDetailsPanel/OrderDetailsPanel.js b/src/components/OrderDetailsPanel/OrderDetailsPanel.js index 4f0006c5..d35a44a2 100644 --- a/src/components/OrderDetailsPanel/OrderDetailsPanel.js +++ b/src/components/OrderDetailsPanel/OrderDetailsPanel.js @@ -14,10 +14,9 @@ const breakdown = transaction => { const bookingStart = booking.attributes.start; const bookingEnd = booking.attributes.end; const payinTotal = tx.attributes.payinTotal; - const payoutTotal = tx.attributes.payoutTotal; const lineItems = tx.attributes.lineItems; - if (!bookingStart || !bookingEnd || !payinTotal || !payoutTotal || !lineItems) { + if (!bookingStart || !bookingEnd || !payinTotal || !lineItems) { return null; } return ( @@ -26,7 +25,6 @@ const breakdown = transaction => { bookingStart={bookingStart} bookingEnd={bookingEnd} payinTotal={payinTotal} - payoutTotal={payoutTotal} lineItems={lineItems} userRole="customer" /> diff --git a/src/components/OrderDetailsPanel/OrderDetailsPanel.test.js b/src/components/OrderDetailsPanel/OrderDetailsPanel.test.js index e5b35643..bee691cc 100644 --- a/src/components/OrderDetailsPanel/OrderDetailsPanel.test.js +++ b/src/components/OrderDetailsPanel/OrderDetailsPanel.test.js @@ -42,6 +42,6 @@ describe('OrderDetailsPanel', () => { }); const panel = shallow(); const breakdownProps = panel.find(BookingBreakdown).props(); - expect(breakdownProps.totalPrice).toEqual(new Money(16500, 'USD')); + expect(breakdownProps.payinTotal).toEqual(new Money(16500, 'USD')); }); }); diff --git a/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap b/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap index d0d51d71..83e33f8b 100644 --- a/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap +++ b/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap @@ -47,17 +47,39 @@ exports[`OrderDetailsPanel matches snapshot 1`] = ` + userRole="customer" />
`; diff --git a/src/components/SaleDetailsPanel/SaleDetailsPanel.test.js b/src/components/SaleDetailsPanel/SaleDetailsPanel.test.js index 10b6e88f..312f1ab1 100644 --- a/src/components/SaleDetailsPanel/SaleDetailsPanel.test.js +++ b/src/components/SaleDetailsPanel/SaleDetailsPanel.test.js @@ -46,6 +46,6 @@ describe('SaleDetailsPanel', () => { const breakdownProps = panel.find(BookingBreakdown).props(); // Total price for the provider should be transaction total minus the commission. - expect(breakdownProps.totalPrice).toEqual(new Money(15500, 'USD')); + expect(breakdownProps.payoutTotal).toEqual(new Money(15500, 'USD')); }); }); diff --git a/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap b/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap index b194fa7f..dbf6ef0f 100644 --- a/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap +++ b/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap @@ -46,23 +46,45 @@ exports[`SaleDetailsPanel matches snapshot 1`] = ` + userRole="provider" />
`; diff --git a/src/containers/BookingDatesForm/BookingDatesForm.js b/src/containers/BookingDatesForm/BookingDatesForm.js index 46c65d58..ed3aada4 100644 --- a/src/containers/BookingDatesForm/BookingDatesForm.js +++ b/src/containers/BookingDatesForm/BookingDatesForm.js @@ -65,6 +65,8 @@ export const BookingDatesFormComponent = props => { price: unitPrice, submitting, intl, + startDatePlaceholder, + endDatePlaceholder, } = props; const { startDate, endDate } = bookingDates; @@ -106,6 +108,9 @@ export const BookingDatesFormComponent = props => { // https://momentjs.com/ const dateFormatString = 'ddd, MMMM D'; + const startDatePlaceholderText = startDatePlaceholder || moment().format(dateFormatString); + const endDatePlaceholderText = endDatePlaceholder || moment().add(1, 'days').format(dateFormatString) + return (
{ name="bookingDates" startDateId={`${form}.bookingStartDate`} startDateLabel={bookingStartLabel} - startDatePlaceholderText={moment().format(dateFormatString)} + startDatePlaceholderText={startDatePlaceholderText} endDateId={`${form}.bookingEndDate`} endDateLabel={bookingEndLabel} - endDatePlaceholderText={moment().add(1, 'days').format(dateFormatString)} + endDatePlaceholderText={endDatePlaceholderText} format={null} useMobileMargins validate={[ @@ -139,6 +144,8 @@ BookingDatesFormComponent.defaultProps = { rootClassName: null, className: null, price: null, + startDatePlaceholder: null, + endDatePlaceholder: null, }; const { instanceOf, shape, string } = PropTypes; @@ -158,6 +165,10 @@ BookingDatesFormComponent.propTypes = { // from inejctIntl intl: intlShape.isRequired, + + // for tests + startDatePlaceholder: string, + endDatePlaceholder: string, }; const formName = 'BookingDates'; diff --git a/src/containers/BookingDatesForm/BookingDatesForm.test.js b/src/containers/BookingDatesForm/BookingDatesForm.test.js index 27c52fa8..b721a022 100644 --- a/src/containers/BookingDatesForm/BookingDatesForm.test.js +++ b/src/containers/BookingDatesForm/BookingDatesForm.test.js @@ -16,6 +16,8 @@ describe('BookingDatesForm', () => { onSubmit={v => v} price={new types.Money(1099, 'USD')} bookingDates={{}} + startDatePlaceholder="today" + endDatePlaceholder="tomorrow" /> ); expect(tree).toMatchSnapshot(); @@ -32,6 +34,8 @@ describe('BookingDatesForm', () => { startDate: new Date(Date.UTC(2017, 3, 14)), endDate: new Date(Date.UTC(2017, 3, 16)), }} + startDatePlaceholder="today" + endDatePlaceholder="tomorrow" /> ); expect(tree).toMatchSnapshot(); diff --git a/src/containers/BookingDatesForm/__snapshots__/BookingDatesForm.test.js.snap b/src/containers/BookingDatesForm/__snapshots__/BookingDatesForm.test.js.snap index 9cbf0688..1b62ac6a 100644 --- a/src/containers/BookingDatesForm/__snapshots__/BookingDatesForm.test.js.snap +++ b/src/containers/BookingDatesForm/__snapshots__/BookingDatesForm.test.js.snap @@ -5,12 +5,12 @@ exports[`BookingDatesForm matches snapshot with selected dates 1`] = ` + } + userRole="customer" />

{ provider = null, lastTransitionedAt = new Date(Date.UTC(2017, 5, 1)), } = options; + const nightCount = booking ? nightsBetween(booking.attributes.start, booking.attributes.end) : 1; return { id: new UUID(id), type: 'transaction', attributes: { - commission, createdAt: new Date(Date.UTC(2017, 4, 1)), lastTransitionedAt, state, - total, + payinTotal: total, + payoutTotal: new Money(total.amount - commission.amount, total.currency), + lineItems: [{ + code: "line-item.purchase/night", + quantity: new Decimal(nightCount), + unitPrice: new Money(total.amount / nightCount, total.currency), + lineTotal: total, + }, { + code: "line-item.commission/provider", + unitPrice: commission, + lineTotal: commission, + }] }, booking, listing, From 096af7c766a9bc7a948f6f5513c4c0b04679d88c Mon Sep 17 00:00:00 2001 From: Mikko Koski Date: Fri, 30 Jun 2017 10:58:12 +0300 Subject: [PATCH 06/11] Fix merge conflicts and run prettier --- .../BookingBreakdown.example.js | 107 ++++++++++-------- .../BookingBreakdown/BookingBreakdown.js | 16 +-- .../BookingBreakdown/BookingBreakdown.test.js | 51 +++++---- .../BookingDatesForm/BookingDatesForm.js | 14 ++- src/util/test-data.js | 23 ++-- 5 files changed, 118 insertions(+), 93 deletions(-) diff --git a/src/components/BookingBreakdown/BookingBreakdown.example.js b/src/components/BookingBreakdown/BookingBreakdown.example.js index a41ffcc0..3050038c 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.example.js +++ b/src/components/BookingBreakdown/BookingBreakdown.example.js @@ -7,13 +7,15 @@ export const Checkout = { props: { bookingStart: new Date(Date.UTC(2017, 3, 14)), bookingEnd: new Date(Date.UTC(2017, 3, 16)), - userRole: "customer", - lineItems: [{ - code: "line-item.purchase/night", - quantity: new Decimal(2), - unitPrice: new types.Money(4500, 'USD'), - lineTotal: new types.Money(9000, 'USD'), - }], + userRole: 'customer', + lineItems: [ + { + code: 'line-item.purchase/night', + quantity: new Decimal(2), + unitPrice: new types.Money(4500, 'USD'), + lineTotal: new types.Money(9000, 'USD'), + }, + ], payinTotal: new types.Money(9000, 'USD'), }, }; @@ -23,13 +25,15 @@ export const CustomerOrder = { props: { bookingStart: new Date(Date.UTC(2017, 3, 14)), bookingEnd: new Date(Date.UTC(2017, 3, 16)), - userRole: "customer", - lineItems: [{ - code: "line-item.purchase/night", - quantity: new Decimal(2), - unitPrice: new types.Money(4500, 'USD'), - lineTotal: new types.Money(9000, 'USD'), - }], + userRole: 'customer', + lineItems: [ + { + code: 'line-item.purchase/night', + quantity: new Decimal(2), + unitPrice: new types.Money(4500, 'USD'), + lineTotal: new types.Money(9000, 'USD'), + }, + ], payinTotal: new types.Money(9000, 'USD'), }, }; @@ -39,17 +43,20 @@ export const ProviderSale = { props: { bookingStart: new Date(Date.UTC(2017, 3, 14)), bookingEnd: new Date(Date.UTC(2017, 3, 16)), - userRole: "provider", - lineItems: [{ - code: "line-item.purchase/night", - quantity: new Decimal(2), - unitPrice: new types.Money(4500, 'USD'), - lineTotal: new types.Money(9000, 'USD'), - }, { - code: "line-item.commission/provider", - unitPrice: new types.Money(-2000, 'USD'), - lineTotal: new types.Money(-2000, 'USD'), - }], + userRole: 'provider', + lineItems: [ + { + code: 'line-item.purchase/night', + quantity: new Decimal(2), + unitPrice: new types.Money(4500, 'USD'), + lineTotal: new types.Money(9000, 'USD'), + }, + { + code: 'line-item.commission/provider', + unitPrice: new types.Money(-2000, 'USD'), + lineTotal: new types.Money(-2000, 'USD'), + }, + ], payoutTotal: new types.Money(7000, 'USD'), }, }; @@ -59,17 +66,20 @@ export const ProviderSaleZeroCommission = { props: { bookingStart: new Date(Date.UTC(2017, 3, 14)), bookingEnd: new Date(Date.UTC(2017, 3, 16)), - userRole: "provider", - lineItems: [{ - code: "line-item.purchase/night", - quantity: new Decimal(2), - unitPrice: new types.Money(4500, 'USD'), - lineTotal: new types.Money(9000, 'USD'), - }, { - code: "line-item.commission/provider", - unitPrice: new types.Money(0, 'USD'), - lineTotal: new types.Money(0, 'USD'), - }], + userRole: 'provider', + lineItems: [ + { + code: 'line-item.purchase/night', + quantity: new Decimal(2), + unitPrice: new types.Money(4500, 'USD'), + lineTotal: new types.Money(9000, 'USD'), + }, + { + code: 'line-item.commission/provider', + unitPrice: new types.Money(0, 'USD'), + lineTotal: new types.Money(0, 'USD'), + }, + ], payoutTotal: new types.Money(9000, 'USD'), }, }; @@ -79,17 +89,20 @@ export const ProviderSaleSingleNight = { props: { bookingStart: new Date(Date.UTC(2017, 3, 14)), bookingEnd: new Date(Date.UTC(2017, 3, 15)), - userRole: "provider", - lineItems: [{ - code: "line-item.purchase/night", - quantity: new Decimal(1), - unitPrice: new types.Money(4500, 'USD'), - lineTotal: new types.Money(4500, 'USD'), - },{ - code: "line-item.commission/provider", - lineTotal: new types.Money(-2000, 'USD'), - unitPrice: new types.Money(-2000, 'USD'), - }], + userRole: 'provider', + lineItems: [ + { + code: 'line-item.purchase/night', + quantity: new Decimal(1), + unitPrice: new types.Money(4500, 'USD'), + lineTotal: new types.Money(4500, 'USD'), + }, + { + code: 'line-item.commission/provider', + unitPrice: new types.Money(-2000, 'USD'), + lineTotal: new types.Money(-2000, 'USD'), + }, + ], payoutTotal: new types.Money(2500, 'USD'), }, }; diff --git a/src/components/BookingBreakdown/BookingBreakdown.js b/src/components/BookingBreakdown/BookingBreakdown.js index 1329f1ee..cc7627a6 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.js +++ b/src/components/BookingBreakdown/BookingBreakdown.js @@ -71,20 +71,20 @@ export const BookingBreakdownComponent = props => { // If commission is passed it will be shown as a fee already reduces from the total price let commissionInfo = null; - if (userRole === "provider") { + if (userRole === 'provider') { const commission = providerCommission.lineTotal; const commissionAsNumber = commission ? convertMoneyToNumber(commission, subUnitDivisor) : 0; const formattedCommission = commission - ? intl.formatNumber(new Decimal(commissionAsNumber).negated().toNumber(), currencyConfig) - : null; + ? intl.formatNumber(new Decimal(commissionAsNumber).negated().toNumber(), currencyConfig) + : null; commissionInfo = (

- - - - {formattedCommission} -
+ + + + {formattedCommission} +
); } diff --git a/src/components/BookingBreakdown/BookingBreakdown.test.js b/src/components/BookingBreakdown/BookingBreakdown.test.js index 7e5183ae..0694464d 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.test.js +++ b/src/components/BookingBreakdown/BookingBreakdown.test.js @@ -13,12 +13,14 @@ describe('BookingBreakdown', () => { bookingEnd={new Date(Date.UTC(2017, 3, 16))} payinTotal={new types.Money(2000, 'USD')} userRole="customer" - lineItems={[{ - code: "line-item.purchase/night", - quantity: new Decimal(2), - lineTotal: new types.Money(2000, 'USD'), - unitPrice: new types.Money(1000, 'USD'), - }]} + lineItems={[ + { + code: 'line-item.purchase/night', + quantity: new Decimal(2), + lineTotal: new types.Money(2000, 'USD'), + unitPrice: new types.Money(1000, 'USD'), + }, + ]} intl={fakeIntl} /> ); @@ -32,12 +34,14 @@ describe('BookingBreakdown', () => { bookingEnd={new Date(Date.UTC(2017, 3, 16))} userRole="customer" payinTotal={new types.Money(2000, 'USD')} - lineItems={[{ - code: "line-item.purchase/night", - quantity: new Decimal(2), - lineTotal: new types.Money(2000, 'USD'), - unitPrice: new types.Money(1000, 'USD'), - }]} + lineItems={[ + { + code: 'line-item.purchase/night', + quantity: new Decimal(2), + lineTotal: new types.Money(2000, 'USD'), + unitPrice: new types.Money(1000, 'USD'), + }, + ]} intl={fakeIntl} /> ); @@ -52,16 +56,19 @@ describe('BookingBreakdown', () => { commission={new types.Money(200, 'USD')} payoutTotal={new types.Money(1800, 'USD')} userRole="provider" - lineItems={[{ - code: "line-item.purchase/night", - quantity: new Decimal(2), - lineTotal: new types.Money(2000, 'USD'), - unitPrice: new types.Money(1000, 'USD'), - }, { - code: "line-item.commission/provider", - lineTotal: new types.Money(200, 'USD'), - unitPrice: new types.Money(200, 'USD'), - }]} + lineItems={[ + { + code: 'line-item.purchase/night', + quantity: new Decimal(2), + lineTotal: new types.Money(2000, 'USD'), + unitPrice: new types.Money(1000, 'USD'), + }, + { + code: 'line-item.commission/provider', + lineTotal: new types.Money(200, 'USD'), + unitPrice: new types.Money(200, 'USD'), + }, + ]} intl={fakeIntl} /> ); diff --git a/src/containers/BookingDatesForm/BookingDatesForm.js b/src/containers/BookingDatesForm/BookingDatesForm.js index ed3aada4..623558a0 100644 --- a/src/containers/BookingDatesForm/BookingDatesForm.js +++ b/src/containers/BookingDatesForm/BookingDatesForm.js @@ -34,12 +34,14 @@ const breakdown = (bookingStart, bookingEnd, unitPrice) => { } const nightCount = nightsBetween(bookingStart, bookingEnd); const totalPrice = estimatedTotalPrice(unitPrice, nightCount); - const lineItems = [{ - code: "line-item.purchase/night", - unitPrice: unitPrice, - quantity: new Decimal(nightCount), - lineTotal: totalPrice, - }]; + const lineItems = [ + { + code: 'line-item.purchase/night', + unitPrice: unitPrice, + quantity: new Decimal(nightCount), + lineTotal: totalPrice, + }, + ]; return ( { state, payinTotal: total, payoutTotal: new Money(total.amount - commission.amount, total.currency), - lineItems: [{ - code: "line-item.purchase/night", - quantity: new Decimal(nightCount), - unitPrice: new Money(total.amount / nightCount, total.currency), - lineTotal: total, - }, { - code: "line-item.commission/provider", - unitPrice: commission, - lineTotal: commission, - }] + lineItems: [ + { + code: 'line-item.purchase/night', + quantity: new Decimal(nightCount), + unitPrice: new Money(total.amount / nightCount, total.currency), + lineTotal: total, + }, + { + code: 'line-item.commission/provider', + unitPrice: commission, + lineTotal: commission, + }, + ], }, booking, listing, From 7ed24991af0c6b98bb79b31a1366f2beda5e57d1 Mon Sep 17 00:00:00 2001 From: Mikko Koski Date: Fri, 30 Jun 2017 11:08:25 +0300 Subject: [PATCH 07/11] Use multiplication sign instead of asterisk --- .../BookingBreakdown/BookingBreakdown.js | 4 +-- .../BookingBreakdown.test.js.snap | 27 ++++++++++++------- src/translations/en.json | 2 +- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/components/BookingBreakdown/BookingBreakdown.js b/src/components/BookingBreakdown/BookingBreakdown.js index cc7627a6..cba586b8 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.js +++ b/src/components/BookingBreakdown/BookingBreakdown.js @@ -4,7 +4,7 @@ */ import _ from 'lodash'; import React, { PropTypes } from 'react'; -import { FormattedMessage, intlShape, injectIntl } from 'react-intl'; +import { FormattedMessage, FormattedHTMLMessage, intlShape, injectIntl } from 'react-intl'; import Decimal from 'decimal.js'; import classNames from 'classnames'; import config from '../../config'; @@ -59,7 +59,7 @@ export const BookingBreakdownComponent = props => { const nightCount = nightPurchase.quantity.toFixed(); const nightCountMessage = ( - + ); const currencyConfig = config.currencyConfig; diff --git a/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap b/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap index 6f0e15fa..259fb269 100644 --- a/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap +++ b/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap @@ -32,9 +32,12 @@ exports[`BookingBreakdown customer transaction data matches snapshot 1`] = ` - - * 2 nights - +
- - * 2 nights - +
- - * 2 nights - +
Date: Fri, 30 Jun 2017 11:29:48 +0300 Subject: [PATCH 08/11] Change all commission amount negative in line items --- .../BookingBreakdown/BookingBreakdown.js | 8 ++------ .../BookingBreakdown/BookingBreakdown.test.js | 4 ++-- .../__snapshots__/BookingBreakdown.test.js.snap | 2 +- .../__snapshots__/OrderDetailsPanel.test.js.snap | 4 ++-- .../__snapshots__/SaleDetailsPanel.test.js.snap | 4 ++-- .../__snapshots__/InboxPage.test.js.snap | 16 ++++++++-------- .../__snapshots__/OrderPage.test.js.snap | 4 ++-- .../SalePage/__snapshots__/SalePage.test.js.snap | 4 ++-- src/util/test-data.js | 4 ++-- 9 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/components/BookingBreakdown/BookingBreakdown.js b/src/components/BookingBreakdown/BookingBreakdown.js index cba586b8..3c627c88 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.js +++ b/src/components/BookingBreakdown/BookingBreakdown.js @@ -2,7 +2,6 @@ * This component will show the booking info and calculated total price. * I.e. dates and other details related to payment decision in receipt format. */ -import _ from 'lodash'; import React, { PropTypes } from 'react'; import { FormattedMessage, FormattedHTMLMessage, intlShape, injectIntl } from 'react-intl'; import Decimal from 'decimal.js'; @@ -51,11 +50,8 @@ export const BookingBreakdownComponent = props => { /> ); - const nightPurchase = _.find(lineItems, item => item.code === 'line-item.purchase/night'); - const providerCommission = _.find( - lineItems, - item => item.code === 'line-item.commission/provider' - ); + const nightPurchase = lineItems.find(item => item.code === 'line-item.purchase/night'); + const providerCommission = lineItems.find(item => item.code === 'line-item.commission/provider'); const nightCount = nightPurchase.quantity.toFixed(); const nightCountMessage = ( diff --git a/src/components/BookingBreakdown/BookingBreakdown.test.js b/src/components/BookingBreakdown/BookingBreakdown.test.js index 0694464d..de17e1ca 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.test.js +++ b/src/components/BookingBreakdown/BookingBreakdown.test.js @@ -65,8 +65,8 @@ describe('BookingBreakdown', () => { }, { code: 'line-item.commission/provider', - lineTotal: new types.Money(200, 'USD'), - unitPrice: new types.Money(200, 'USD'), + lineTotal: new types.Money(-200, 'USD'), + unitPrice: new types.Money(-200, 'USD'), }, ]} intl={fakeIntl} diff --git a/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap b/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap index 259fb269..2d22d38e 100644 --- a/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap +++ b/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap @@ -170,7 +170,7 @@ exports[`BookingBreakdown provider transaction data matches snapshot 1`] = ` - -2 + 2

{ }, { code: 'line-item.commission/provider', - unitPrice: commission, - lineTotal: commission, + unitPrice: new Money(commission.amount * -1, commission.currency), + lineTotal: new Money(commission.amount * -1, commission.currency), }, ], }, From a0cf29474858c2c130c03bf30b53e7d42035237d Mon Sep 17 00:00:00 2001 From: Mikko Koski Date: Fri, 30 Jun 2017 11:34:25 +0300 Subject: [PATCH 09/11] Ensure that the either payinTotal/payoutTotal is provided --- src/components/BookingBreakdown/BookingBreakdown.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/BookingBreakdown/BookingBreakdown.js b/src/components/BookingBreakdown/BookingBreakdown.js index 3c627c88..4c910317 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.js +++ b/src/components/BookingBreakdown/BookingBreakdown.js @@ -27,6 +27,14 @@ export const BookingBreakdownComponent = props => { const classes = classNames(rootClassName || css.root, className); + if (userRole === "customer" && !payinTotal) { + throw new Error('payinTotal is required for customer breakdown'); + } + + if (userRole === "provider" && !payoutTotal) { + throw new Error('payoutTotal is required for provider breakdown'); + } + const dateFormatOptions = { weekday: 'short', month: 'long', From 47e9adb85b6eedc59960bd4846878a2f15098a5f Mon Sep 17 00:00:00 2001 From: Mikko Koski Date: Fri, 30 Jun 2017 12:14:39 +0300 Subject: [PATCH 10/11] Update line item code keywords --- .../BookingBreakdown/BookingBreakdown.example.js | 16 ++++++++-------- .../BookingBreakdown/BookingBreakdown.js | 4 ++-- .../BookingBreakdown/BookingBreakdown.test.js | 8 ++++---- .../__snapshots__/OrderDetailsPanel.test.js.snap | 4 ++-- .../__snapshots__/SaleDetailsPanel.test.js.snap | 4 ++-- .../__snapshots__/InboxPage.test.js.snap | 16 ++++++++-------- .../__snapshots__/OrderPage.test.js.snap | 4 ++-- .../SalePage/__snapshots__/SalePage.test.js.snap | 4 ++-- src/util/test-data.js | 4 ++-- 9 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/components/BookingBreakdown/BookingBreakdown.example.js b/src/components/BookingBreakdown/BookingBreakdown.example.js index 3050038c..d578b693 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.example.js +++ b/src/components/BookingBreakdown/BookingBreakdown.example.js @@ -10,7 +10,7 @@ export const Checkout = { userRole: 'customer', lineItems: [ { - code: 'line-item.purchase/night', + code: 'line-item/night', quantity: new Decimal(2), unitPrice: new types.Money(4500, 'USD'), lineTotal: new types.Money(9000, 'USD'), @@ -28,7 +28,7 @@ export const CustomerOrder = { userRole: 'customer', lineItems: [ { - code: 'line-item.purchase/night', + code: 'line-item/night', quantity: new Decimal(2), unitPrice: new types.Money(4500, 'USD'), lineTotal: new types.Money(9000, 'USD'), @@ -46,13 +46,13 @@ export const ProviderSale = { userRole: 'provider', lineItems: [ { - code: 'line-item.purchase/night', + code: 'line-item/night', quantity: new Decimal(2), unitPrice: new types.Money(4500, 'USD'), lineTotal: new types.Money(9000, 'USD'), }, { - code: 'line-item.commission/provider', + code: 'line-item/provider-commission', unitPrice: new types.Money(-2000, 'USD'), lineTotal: new types.Money(-2000, 'USD'), }, @@ -69,13 +69,13 @@ export const ProviderSaleZeroCommission = { userRole: 'provider', lineItems: [ { - code: 'line-item.purchase/night', + code: 'line-item/night', quantity: new Decimal(2), unitPrice: new types.Money(4500, 'USD'), lineTotal: new types.Money(9000, 'USD'), }, { - code: 'line-item.commission/provider', + code: 'line-item/provider-commission', unitPrice: new types.Money(0, 'USD'), lineTotal: new types.Money(0, 'USD'), }, @@ -92,13 +92,13 @@ export const ProviderSaleSingleNight = { userRole: 'provider', lineItems: [ { - code: 'line-item.purchase/night', + code: 'line-item/night', quantity: new Decimal(1), unitPrice: new types.Money(4500, 'USD'), lineTotal: new types.Money(4500, 'USD'), }, { - code: 'line-item.commission/provider', + code: 'line-item/provider-commission', unitPrice: new types.Money(-2000, 'USD'), lineTotal: new types.Money(-2000, 'USD'), }, diff --git a/src/components/BookingBreakdown/BookingBreakdown.js b/src/components/BookingBreakdown/BookingBreakdown.js index 4c910317..295e4a25 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.js +++ b/src/components/BookingBreakdown/BookingBreakdown.js @@ -58,8 +58,8 @@ export const BookingBreakdownComponent = props => { /> ); - const nightPurchase = lineItems.find(item => item.code === 'line-item.purchase/night'); - const providerCommission = lineItems.find(item => item.code === 'line-item.commission/provider'); + const nightPurchase = lineItems.find(item => item.code === 'line-item/night'); + const providerCommission = lineItems.find(item => item.code === 'line-item/provider-commission'); const nightCount = nightPurchase.quantity.toFixed(); const nightCountMessage = ( diff --git a/src/components/BookingBreakdown/BookingBreakdown.test.js b/src/components/BookingBreakdown/BookingBreakdown.test.js index de17e1ca..9d42041a 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.test.js +++ b/src/components/BookingBreakdown/BookingBreakdown.test.js @@ -15,7 +15,7 @@ describe('BookingBreakdown', () => { userRole="customer" lineItems={[ { - code: 'line-item.purchase/night', + code: 'line-item/night', quantity: new Decimal(2), lineTotal: new types.Money(2000, 'USD'), unitPrice: new types.Money(1000, 'USD'), @@ -36,7 +36,7 @@ describe('BookingBreakdown', () => { payinTotal={new types.Money(2000, 'USD')} lineItems={[ { - code: 'line-item.purchase/night', + code: 'line-item/night', quantity: new Decimal(2), lineTotal: new types.Money(2000, 'USD'), unitPrice: new types.Money(1000, 'USD'), @@ -58,13 +58,13 @@ describe('BookingBreakdown', () => { userRole="provider" lineItems={[ { - code: 'line-item.purchase/night', + code: 'line-item/night', quantity: new Decimal(2), lineTotal: new types.Money(2000, 'USD'), unitPrice: new types.Money(1000, 'USD'), }, { - code: 'line-item.commission/provider', + code: 'line-item/provider-commission', lineTotal: new types.Money(-200, 'USD'), unitPrice: new types.Money(-200, 'USD'), }, diff --git a/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap b/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap index 7d67ee13..37c2fe32 100644 --- a/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap +++ b/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap @@ -50,7 +50,7 @@ exports[`OrderDetailsPanel matches snapshot 1`] = ` lineItems={ Array [ Object { - "code": "line-item.purchase/night", + "code": "line-item/night", "lineTotal": Money { "amount": 16500, "currency": "USD", @@ -62,7 +62,7 @@ exports[`OrderDetailsPanel matches snapshot 1`] = ` }, }, Object { - "code": "line-item.commission/provider", + "code": "line-item/provider-commission", "lineTotal": Money { "amount": -100, "currency": "USD", diff --git a/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap b/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap index 91dec9bc..63bd0907 100644 --- a/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap +++ b/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap @@ -49,7 +49,7 @@ exports[`SaleDetailsPanel matches snapshot 1`] = ` lineItems={ Array [ Object { - "code": "line-item.purchase/night", + "code": "line-item/night", "lineTotal": Money { "amount": 16500, "currency": "USD", @@ -61,7 +61,7 @@ exports[`SaleDetailsPanel matches snapshot 1`] = ` }, }, Object { - "code": "line-item.commission/provider", + "code": "line-item/provider-commission", "lineTotal": Money { "amount": -1000, "currency": "USD", diff --git a/src/containers/InboxPage/__snapshots__/InboxPage.test.js.snap b/src/containers/InboxPage/__snapshots__/InboxPage.test.js.snap index 06c9e018..7713fd9f 100644 --- a/src/containers/InboxPage/__snapshots__/InboxPage.test.js.snap +++ b/src/containers/InboxPage/__snapshots__/InboxPage.test.js.snap @@ -54,7 +54,7 @@ exports[`InboxPage matches snapshot 1`] = ` "lastTransitionedAt": 2017-01-15T00:00:00.000Z, "lineItems": Array [ Object { - "code": "line-item.purchase/night", + "code": "line-item/night", "lineTotal": Money { "amount": 1000, "currency": "USD", @@ -66,7 +66,7 @@ exports[`InboxPage matches snapshot 1`] = ` }, }, Object { - "code": "line-item.commission/provider", + "code": "line-item/provider-commission", "lineTotal": Money { "amount": -100, "currency": "USD", @@ -131,7 +131,7 @@ exports[`InboxPage matches snapshot 1`] = ` "lastTransitionedAt": 2016-01-15T00:00:00.000Z, "lineItems": Array [ Object { - "code": "line-item.purchase/night", + "code": "line-item/night", "lineTotal": Money { "amount": 1000, "currency": "USD", @@ -143,7 +143,7 @@ exports[`InboxPage matches snapshot 1`] = ` }, }, Object { - "code": "line-item.commission/provider", + "code": "line-item/provider-commission", "lineTotal": Money { "amount": -100, "currency": "USD", @@ -285,7 +285,7 @@ exports[`InboxPage matches snapshot 3`] = ` "lastTransitionedAt": 2017-01-15T00:00:00.000Z, "lineItems": Array [ Object { - "code": "line-item.purchase/night", + "code": "line-item/night", "lineTotal": Money { "amount": 1000, "currency": "USD", @@ -297,7 +297,7 @@ exports[`InboxPage matches snapshot 3`] = ` }, }, Object { - "code": "line-item.commission/provider", + "code": "line-item/provider-commission", "lineTotal": Money { "amount": -100, "currency": "USD", @@ -362,7 +362,7 @@ exports[`InboxPage matches snapshot 3`] = ` "lastTransitionedAt": 2016-01-15T00:00:00.000Z, "lineItems": Array [ Object { - "code": "line-item.purchase/night", + "code": "line-item/night", "lineTotal": Money { "amount": 1000, "currency": "USD", @@ -374,7 +374,7 @@ exports[`InboxPage matches snapshot 3`] = ` }, }, Object { - "code": "line-item.commission/provider", + "code": "line-item/provider-commission", "lineTotal": Money { "amount": -100, "currency": "USD", diff --git a/src/containers/OrderPage/__snapshots__/OrderPage.test.js.snap b/src/containers/OrderPage/__snapshots__/OrderPage.test.js.snap index ab2ca05b..bb96dc31 100644 --- a/src/containers/OrderPage/__snapshots__/OrderPage.test.js.snap +++ b/src/containers/OrderPage/__snapshots__/OrderPage.test.js.snap @@ -12,7 +12,7 @@ exports[`OrderPage matches snapshot 1`] = ` "lastTransitionedAt": 2017-06-01T00:00:00.000Z, "lineItems": Array [ Object { - "code": "line-item.purchase/night", + "code": "line-item/night", "lineTotal": Money { "amount": 1000, "currency": "USD", @@ -24,7 +24,7 @@ exports[`OrderPage matches snapshot 1`] = ` }, }, Object { - "code": "line-item.commission/provider", + "code": "line-item/provider-commission", "lineTotal": Money { "amount": -100, "currency": "USD", diff --git a/src/containers/SalePage/__snapshots__/SalePage.test.js.snap b/src/containers/SalePage/__snapshots__/SalePage.test.js.snap index 123396a1..64a864bb 100644 --- a/src/containers/SalePage/__snapshots__/SalePage.test.js.snap +++ b/src/containers/SalePage/__snapshots__/SalePage.test.js.snap @@ -13,7 +13,7 @@ exports[`SalePage matches snapshot 1`] = ` "lastTransitionedAt": 2017-06-01T00:00:00.000Z, "lineItems": Array [ Object { - "code": "line-item.purchase/night", + "code": "line-item/night", "lineTotal": Money { "amount": 1000, "currency": "USD", @@ -25,7 +25,7 @@ exports[`SalePage matches snapshot 1`] = ` }, }, Object { - "code": "line-item.commission/provider", + "code": "line-item/provider-commission", "lineTotal": Money { "amount": -100, "currency": "USD", diff --git a/src/util/test-data.js b/src/util/test-data.js index 80e26f98..a39f6cee 100644 --- a/src/util/test-data.js +++ b/src/util/test-data.js @@ -94,13 +94,13 @@ export const createTransaction = options => { payoutTotal: new Money(total.amount - commission.amount, total.currency), lineItems: [ { - code: 'line-item.purchase/night', + code: 'line-item/night', quantity: new Decimal(nightCount), unitPrice: new Money(total.amount / nightCount, total.currency), lineTotal: total, }, { - code: 'line-item.commission/provider', + code: 'line-item/provider-commission', unitPrice: new Money(commission.amount * -1, commission.currency), lineTotal: new Money(commission.amount * -1, commission.currency), }, From adcc5f9277dc25bfc5fa094e17ac4aaf5a3f1c29 Mon Sep 17 00:00:00 2001 From: Vesa Luusua Date: Sun, 2 Jul 2017 10:24:46 +0300 Subject: [PATCH 11/11] run prettier --- src/components/BookingBreakdown/BookingBreakdown.js | 4 ++-- src/containers/BookingDatesForm/BookingDatesForm.js | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/BookingBreakdown/BookingBreakdown.js b/src/components/BookingBreakdown/BookingBreakdown.js index 295e4a25..4f30bdfb 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.js +++ b/src/components/BookingBreakdown/BookingBreakdown.js @@ -27,11 +27,11 @@ export const BookingBreakdownComponent = props => { const classes = classNames(rootClassName || css.root, className); - if (userRole === "customer" && !payinTotal) { + if (userRole === 'customer' && !payinTotal) { throw new Error('payinTotal is required for customer breakdown'); } - if (userRole === "provider" && !payoutTotal) { + if (userRole === 'provider' && !payoutTotal) { throw new Error('payoutTotal is required for provider breakdown'); } diff --git a/src/containers/BookingDatesForm/BookingDatesForm.js b/src/containers/BookingDatesForm/BookingDatesForm.js index 623558a0..e7af8ce4 100644 --- a/src/containers/BookingDatesForm/BookingDatesForm.js +++ b/src/containers/BookingDatesForm/BookingDatesForm.js @@ -111,7 +111,8 @@ export const BookingDatesFormComponent = props => { const dateFormatString = 'ddd, MMMM D'; const startDatePlaceholderText = startDatePlaceholder || moment().format(dateFormatString); - const endDatePlaceholderText = endDatePlaceholder || moment().add(1, 'days').format(dateFormatString) + const endDatePlaceholderText = endDatePlaceholder || + moment().add(1, 'days').format(dateFormatString); return (