From b44828045d90fe89314a4193e6da253f6c1a46b3 Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Wed, 3 Jan 2018 14:34:31 +0200 Subject: [PATCH] Add support for daily breakdowns --- .../BookingBreakdown.example.js | 52 +++++++++++++++++++ .../BookingBreakdown/BookingBreakdown.js | 30 +++++++---- .../BookingBreakdown.test.js.snap | 16 +++--- .../BookingDatesForm/BookingDatesForm.js | 3 +- src/translations/en.json | 6 ++- 5 files changed, 87 insertions(+), 20 deletions(-) diff --git a/src/components/BookingBreakdown/BookingBreakdown.example.js b/src/components/BookingBreakdown/BookingBreakdown.example.js index c1622a92..c19ca9c7 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.example.js +++ b/src/components/BookingBreakdown/BookingBreakdown.example.js @@ -410,3 +410,55 @@ export const ProviderSaleCanceled = { }), }, }; + +export const SingleDay = { + component: BookingBreakdown, + props: { + userRole: 'customer', + unitType: propTypes.LINE_ITEM_DAY, + transaction: exampleTransaction({ + payinTotal: new Money(4500, CURRENCY), + payoutTotal: new Money(4500, CURRENCY), + lineItems: [ + { + code: 'line-item/day', + includeFor: ['customer', 'provider'], + quantity: new Decimal(1), + unitPrice: new Money(4500, CURRENCY), + lineTotal: new Money(4500, CURRENCY), + reversal: false, + }, + ], + }), + booking: exampleBooking({ + start: new Date(Date.UTC(2017, 3, 14)), + end: new Date(Date.UTC(2017, 3, 15)), + }), + }, +}; + +export const MultipleDays = { + component: BookingBreakdown, + props: { + userRole: 'customer', + unitType: propTypes.LINE_ITEM_DAY, + transaction: exampleTransaction({ + payinTotal: new Money(9000, CURRENCY), + payoutTotal: new Money(9000, CURRENCY), + lineItems: [ + { + code: 'line-item/day', + includeFor: ['customer', 'provider'], + quantity: new Decimal(2), + unitPrice: new Money(4500, CURRENCY), + lineTotal: new Money(9000, CURRENCY), + reversal: false, + }, + ], + }), + booking: exampleBooking({ + start: new Date(Date.UTC(2017, 3, 14)), + end: new Date(Date.UTC(2017, 3, 16)), + }), + }, +}; diff --git a/src/components/BookingBreakdown/BookingBreakdown.js b/src/components/BookingBreakdown/BookingBreakdown.js index 55eb3c6f..054f6450 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.js +++ b/src/components/BookingBreakdown/BookingBreakdown.js @@ -5,10 +5,12 @@ import React from 'react'; import { bool, oneOf, string } from 'prop-types'; import { FormattedMessage, FormattedHTMLMessage, intlShape, injectIntl } from 'react-intl'; +import moment from 'moment'; import classNames from 'classnames'; import { types } from '../../util/sdkLoader'; import { formatMoney } from '../../util/currency'; import * as propTypes from '../../util/propTypes'; +import { daysBetween } from '../../util/dates'; import css from './BookingBreakdown.css'; @@ -26,6 +28,7 @@ const isValidCommission = commissionLineItem => { const UnitPriceItem = props => { const { transaction, unitType, intl } = props; + const isNightly = unitType === propTypes.LINE_ITEM_NIGHT; const unitPurchase = transaction.attributes.lineItems.find( item => item.code === unitType && !item.reversal ); @@ -34,7 +37,9 @@ const UnitPriceItem = props => { return (
- + {formattedUnitPrice}
@@ -50,24 +55,28 @@ UnitPriceItem.propTypes = { const UnitsItem = props => { const { transaction, booking, unitType, intl } = props; + const { start: startDate, end: endDateRaw } = booking.attributes; + const isNightly = unitType === propTypes.LINE_ITEM_NIGHT; + const isSingleDay = !isNightly && daysBetween(startDate, endDateRaw) === 1; + + const endDay = isNightly ? endDateRaw : moment(endDateRaw).subtract(1, 'days'); + const dateFormatOptions = { weekday: 'short', month: 'short', day: 'numeric', }; - const bookingPeriod = ( + const bookingPeriod = isSingleDay ? ( + intl.formatDate(startDate, dateFormatOptions) + ) : ( - {intl.formatDate(booking.attributes.start, dateFormatOptions)} - + {intl.formatDate(startDate, dateFormatOptions)} ), bookingEnd: ( - - {intl.formatDate(booking.attributes.end, dateFormatOptions)} - + {intl.formatDate(endDay, dateFormatOptions)} ), }} /> @@ -77,7 +86,10 @@ const UnitsItem = props => { ); const unitCount = unitPurchase.quantity.toFixed(); const unitCountMessage = ( - + ); return ( diff --git a/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap b/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap index 881fa2f0..2af3179a 100644 --- a/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap +++ b/src/components/BookingBreakdown/__snapshots__/BookingBreakdown.test.js.snap @@ -11,7 +11,7 @@ exports[`BookingBreakdown customer transaction data matches snapshot 1`] = ` className={undefined} > - BookingBreakdown.pricePerUnit + BookingBreakdown.pricePerNight @@ -75,7 +75,7 @@ exports[`BookingBreakdown pretransaction data matches snapshot 1`] = ` className={undefined} > - BookingBreakdown.pricePerUnit + BookingBreakdown.pricePerNight @@ -139,7 +139,7 @@ exports[`BookingBreakdown provider canceled transaction data matches snapshot 1` className={undefined} > - BookingBreakdown.pricePerUnit + BookingBreakdown.pricePerNight @@ -235,7 +235,7 @@ exports[`BookingBreakdown provider transaction data matches snapshot 1`] = ` className={undefined} > - BookingBreakdown.pricePerUnit + BookingBreakdown.pricePerNight diff --git a/src/containers/BookingDatesForm/BookingDatesForm.js b/src/containers/BookingDatesForm/BookingDatesForm.js index 76745d19..9f2fd4e0 100644 --- a/src/containers/BookingDatesForm/BookingDatesForm.js +++ b/src/containers/BookingDatesForm/BookingDatesForm.js @@ -45,7 +45,7 @@ const estimatedNightlyTransaction = (bookingStart, bookingEnd, unitPrice) => { payoutTotal: totalPrice, lineItems: [ { - code: 'line-item/night', + code: propTypes.LINE_ITEM_NIGHT, includeFor: ['customer', 'provider'], unitPrice: unitPrice, quantity: new Decimal(nightCount), @@ -78,6 +78,7 @@ const estimatedBreakdown = (bookingStart, bookingEnd, unitPrice) => { return null; } + // TODO: estimate daily tx if config is set const tx = estimatedNightlyTransaction(bookingStart, bookingEnd, unitPrice); return ( diff --git a/src/translations/en.json b/src/translations/en.json index 18dd9ead..160ced5c 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -39,7 +39,10 @@ "Avatar.bannedUserDisplayName": "Banned user", "BookingBreakdown.bookingPeriod": "{bookingStart} – {bookingEnd}", "BookingBreakdown.commission": "Saunatime fee", - "BookingBreakdown.pricePerUnit": "Price per night", + "BookingBreakdown.dayCount": "{count, number} {count, plural, one {day} other {days}}", + "BookingBreakdown.nightCount": "{count, number} {count, plural, one {night} other {nights}}", + "BookingBreakdown.pricePerDay": "Price per day", + "BookingBreakdown.pricePerNight": "Price per night", "BookingBreakdown.providerTotalCanceled": "Total price", "BookingBreakdown.providerTotalDeclined": "You would have made", "BookingBreakdown.providerTotalDefault": "You'll make", @@ -47,7 +50,6 @@ "BookingBreakdown.refund": "Refund", "BookingBreakdown.subTotal": "Subtotal", "BookingBreakdown.total": "Total price", - "BookingBreakdown.unitCount": "{count, number} {count, plural, one {night} other {nights}}", "BookingDatesForm.bookingEndTitle": "End date", "BookingDatesForm.bookingStartTitle": "Start date", "BookingDatesForm.listingCurrencyInvalid": "Oops, the currency of the listing doesn't match the currency of the marketplace.",