Add support for daily breakdowns

This commit is contained in:
Kimmo Puputti 2018-01-03 14:34:31 +02:00
parent dc73569da6
commit b44828045d
5 changed files with 87 additions and 20 deletions

View file

@ -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)),
}),
},
};

View file

@ -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 (
<div className={css.lineItem}>
<span className={css.itemLabel}>
<FormattedMessage id="BookingBreakdown.pricePerUnit" />
<FormattedMessage
id={isNightly ? 'BookingBreakdown.pricePerNight' : 'BookingBreakdown.pricePerDay'}
/>
</span>
<span className={css.itemValue}>{formattedUnitPrice}</span>
</div>
@ -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)
) : (
<FormattedMessage
id="BookingBreakdown.bookingPeriod"
values={{
bookingStart: (
<span className={css.nowrap}>
{intl.formatDate(booking.attributes.start, dateFormatOptions)}
</span>
<span className={css.nowrap}>{intl.formatDate(startDate, dateFormatOptions)}</span>
),
bookingEnd: (
<span className={css.nowrap}>
{intl.formatDate(booking.attributes.end, dateFormatOptions)}
</span>
<span className={css.nowrap}>{intl.formatDate(endDay, dateFormatOptions)}</span>
),
}}
/>
@ -77,7 +86,10 @@ const UnitsItem = props => {
);
const unitCount = unitPurchase.quantity.toFixed();
const unitCountMessage = (
<FormattedHTMLMessage id="BookingBreakdown.unitCount" values={{ count: unitCount }} />
<FormattedHTMLMessage
id={isNightly ? 'BookingBreakdown.nightCount' : 'BookingBreakdown.dayCount'}
values={{ count: unitCount }}
/>
);
return (

View file

@ -11,7 +11,7 @@ exports[`BookingBreakdown customer transaction data matches snapshot 1`] = `
className={undefined}
>
<span>
BookingBreakdown.pricePerUnit
BookingBreakdown.pricePerNight
</span>
</span>
<span
@ -36,7 +36,7 @@ exports[`BookingBreakdown customer transaction data matches snapshot 1`] = `
<span
dangerouslySetInnerHTML={
Object {
"__html": "BookingBreakdown.unitCount",
"__html": "BookingBreakdown.nightCount",
}
}
/>
@ -75,7 +75,7 @@ exports[`BookingBreakdown pretransaction data matches snapshot 1`] = `
className={undefined}
>
<span>
BookingBreakdown.pricePerUnit
BookingBreakdown.pricePerNight
</span>
</span>
<span
@ -100,7 +100,7 @@ exports[`BookingBreakdown pretransaction data matches snapshot 1`] = `
<span
dangerouslySetInnerHTML={
Object {
"__html": "BookingBreakdown.unitCount",
"__html": "BookingBreakdown.nightCount",
}
}
/>
@ -139,7 +139,7 @@ exports[`BookingBreakdown provider canceled transaction data matches snapshot 1`
className={undefined}
>
<span>
BookingBreakdown.pricePerUnit
BookingBreakdown.pricePerNight
</span>
</span>
<span
@ -164,7 +164,7 @@ exports[`BookingBreakdown provider canceled transaction data matches snapshot 1`
<span
dangerouslySetInnerHTML={
Object {
"__html": "BookingBreakdown.unitCount",
"__html": "BookingBreakdown.nightCount",
}
}
/>
@ -235,7 +235,7 @@ exports[`BookingBreakdown provider transaction data matches snapshot 1`] = `
className={undefined}
>
<span>
BookingBreakdown.pricePerUnit
BookingBreakdown.pricePerNight
</span>
</span>
<span
@ -260,7 +260,7 @@ exports[`BookingBreakdown provider transaction data matches snapshot 1`] = `
<span
dangerouslySetInnerHTML={
Object {
"__html": "BookingBreakdown.unitCount",
"__html": "BookingBreakdown.nightCount",
}
}
/>

View file

@ -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 (

View file

@ -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.",