Skip to content

Commit

Permalink
MPDX-8347 Round converted donations (#1126)
Browse files Browse the repository at this point in the history
* Round converted foreign donations and add tooltips
  • Loading branch information
caleballdrin authored Oct 14, 2024
1 parent 708ad91 commit 7bc3cb5
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 21 deletions.
34 changes: 20 additions & 14 deletions src/components/DonationTable/DonationTable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ const TestComponent: React.FC<TestComponentProps> = ({
{
id: 'donation-1',
amount: {
amount: 10,
convertedAmount: 10,
amount: 11.55,
convertedAmount: 11.55,
convertedCurrency: 'CAD',
currency: 'CAD',
},
Expand All @@ -85,8 +85,8 @@ const TestComponent: React.FC<TestComponentProps> = ({
{
id: 'donation-2',
amount: {
amount: hasForeignCurrency ? 200 : 100,
convertedAmount: 100,
amount: hasForeignCurrency ? 200.55 : 100,
convertedAmount: hasForeignCurrency ? 100.89 : 100,
convertedCurrency: 'CAD',
currency: hasForeignCurrency ? 'USD' : 'CAD',
},
Expand Down Expand Up @@ -139,7 +139,7 @@ describe('DonationTable', () => {

expect(await findByRole('cell', { name: 'Donor 1' })).toBeInTheDocument();
expect(getByRole('cell', { name: 'Donor 2' })).toBeInTheDocument();
expect(getByRole('cell', { name: 'CA$10' })).toBeInTheDocument();
expect(getByRole('cell', { name: 'CA$11.55' })).toBeInTheDocument();
expect(getByRole('cell', { name: 'CA$100' })).toBeInTheDocument();
expect(getByRole('cell', { name: '3/1/2023' })).toBeInTheDocument();
expect(getByRole('cell', { name: '3/2/2023' })).toBeInTheDocument();
Expand Down Expand Up @@ -242,28 +242,34 @@ describe('DonationTable', () => {
await findByRole('table', { name: 'Donation Totals' }),
).getByRole('row');
expect(totalRow.children[0]).toHaveTextContent('Total Donations:');
expect(totalRow.children[1]).toHaveTextContent('CA$110');
expect(totalRow.children[1]).toHaveTextContent('CA$111.55');
});

it('shows currency column and additional total rows when a currency does not match the account currency', async () => {
const { findByRole } = render(<TestComponent hasForeignCurrency />);
const { findByRole, getAllByRole } = render(
<TestComponent hasForeignCurrency />,
);

expect(
await findByRole('columnheader', { name: 'Foreign Amount' }),
).toBeInTheDocument();
expect(await findByRole('cell', { name: 'Donor 1' })).toBeInTheDocument();
// a donation with the same currency as the contact is not rounded
// It should be found 4 times - two in the donation table and two in the totals table
expect(getAllByRole('cell', { name: 'CA$11.55' })).toHaveLength(4);

const totalsRows = within(
await findByRole('table', { name: 'Donation Totals' }),
).getAllByRole('row');
expect(totalsRows).toHaveLength(4);
expect(totalsRows[1].children[0]).toHaveTextContent('Total CAD Donations:');
expect(totalsRows[1].children[1]).toHaveTextContent('CA$10');
expect(totalsRows[1].children[2]).toHaveTextContent('CA$10');
expect(totalsRows[1].children[1]).toHaveTextContent('CA$11.55');
expect(totalsRows[1].children[2]).toHaveTextContent('CA$11.55');
expect(totalsRows[2].children[0]).toHaveTextContent('Total USD Donations:');
expect(totalsRows[2].children[1]).toHaveTextContent('CA$100');
expect(totalsRows[2].children[2]).toHaveTextContent('$200');
expect(totalsRows[2].children[1]).toHaveTextContent('CA$101');
expect(totalsRows[2].children[2]).toHaveTextContent('$200.55');
expect(totalsRows[3].children[0]).toHaveTextContent('Total Donations:');
expect(totalsRows[3].children[1]).toHaveTextContent('CA$110');
expect(totalsRows[3].children[1]).toHaveTextContent('CA$112');
});

it('updates the sort order', async () => {
Expand All @@ -276,13 +282,13 @@ describe('DonationTable', () => {

userEvent.click(await findByRole('columnheader', { name: 'Amount' }));
const cellsAsc = getAllByRole('cell', { name: /CA/ });
expect(cellsAsc[0]).toHaveTextContent('CA$10');
expect(cellsAsc[0]).toHaveTextContent('CA$11.55');
expect(cellsAsc[1]).toHaveTextContent('CA$100');

userEvent.click(await findByRole('columnheader', { name: 'Amount' }));
const cellsDesc = getAllByRole('cell', { name: /CA/ });
expect(cellsDesc[0]).toHaveTextContent('CA$100');
expect(cellsDesc[1]).toHaveTextContent('CA$10');
expect(cellsDesc[1]).toHaveTextContent('CA$11.55');
});

it('loads multiple pages and shows the progress bar', async () => {
Expand Down
69 changes: 62 additions & 7 deletions src/components/DonationTable/DonationTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
TableHead,
TableRow,
Tooltip,
Typography,
} from '@mui/material';
import IconButton from '@mui/material/IconButton';
import { styled } from '@mui/material/styles';
Expand Down Expand Up @@ -93,6 +94,12 @@ export const LoadingIndicator = styled(CircularProgress)(({ theme }) => ({
margin: theme.spacing(0, 1, 0, 0),
}));

const DashUnderlineTypography = styled(Typography)(() => ({
borderBottom: '1px dashed black',
display: 'inline',
fontSize: 'inherit',
}));

export interface DonationRow {
id: string;
date: DateTime;
Expand Down Expand Up @@ -203,8 +210,33 @@ export const DonationTable: React.FC<DonationTableProps> = ({
</Tooltip>
);

const amount: RenderCell = ({ row }) =>
currencyFormat(row.convertedAmount, row.currency, locale);
const amount: RenderCell = ({ row }) => {
if (row.currency !== row.foreignCurrency) {
return (
<Tooltip
arrow
placement="bottom"
title={t(
'Conversion rate of {{rate}}. This conversion is approximate.',
{
rate: (row.convertedAmount / row.foreignAmount).toFixed(4),
},
)}
>
{/* We are rounding to avoid confusion. The number displayed won't exactly match the number in their account due to variations in exchange rates */}
<DashUnderlineTypography>
{currencyFormat(
Math.round(row.convertedAmount),
row.currency,
locale,
)}
</DashUnderlineTypography>
</Tooltip>
);
} else {
return currencyFormat(row.convertedAmount, row.currency, locale);
}
};

const foreignAmount: RenderCell = ({ row }) =>
currencyFormat(row.foreignAmount, row.foreignCurrency, locale);
Expand Down Expand Up @@ -379,10 +411,27 @@ export const DonationTable: React.FC<DonationTableProps> = ({
{t('Total {{currency}} Donations:', { currency })}
</TableCell>
<TableCell>
{currencyFormat(
total.convertedTotal,
accountCurrency,
locale,
{accountCurrency !== currency ? (
<Tooltip
arrow
title={t('This conversion is approximate')}
>
<DashUnderlineTypography>
{currencyFormat(
Math.round(total.convertedTotal),
accountCurrency,
locale,
)}
</DashUnderlineTypography>
</Tooltip>
) : (
<>
{currencyFormat(
total.convertedTotal,
accountCurrency,
locale,
)}
</>
)}
</TableCell>
<TableCell>
Expand All @@ -397,7 +446,13 @@ export const DonationTable: React.FC<DonationTableProps> = ({
{t('Total Donations: ')}
</TableCell>
<TableCell style={{ width: 100 }}>
{currencyFormat(totalDonations, accountCurrency, locale)}
{currencyFormat(
hasForeignDonations
? Math.round(totalDonations)
: totalDonations,
accountCurrency,
locale,
)}
</TableCell>
<TableCell />
</TableRow>
Expand Down

0 comments on commit 7bc3cb5

Please sign in to comment.