Skip to content

Commit

Permalink
Resend the export win email to the customer (#6565)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulgain authored Feb 29, 2024
1 parent 8d81417 commit 36fe440
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 164 deletions.
3 changes: 1 addition & 2 deletions src/client/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,7 @@ export const COPY_TASK_DETAILS_LOADED = 'COPY_TASK_DETAILS_LOADED'

export const INVESTMENT__PROJECT_LOADED = 'INVESTMENT__PROJECT_LOADED'

export const EXPORT_WINS__CONFIRMED_LOADED = 'EXPORT_WINS__CONFIRMED_LOADED'
export const EXPORT_WINS__DETAILS_LOADED = 'EXPORT_WINS__DETAILS_LOADED'
export const EXPORT_WIN_RESENT__SUCCESS = 'EXPORT_WIN_RESENT__SUCCESS'

export const PAGINATED_RESOURCE__GO_TO_PAGE = 'PAGINATED_RESOURCE__GO_TO_PAGE'
export const PAGINATED_RESOURCE__ON_SUCCESS = 'PAGINATED_RESOURCE__ON_SUCCESS'
Expand Down
2 changes: 1 addition & 1 deletion src/client/modules/ExportPipeline/ExportDetails/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ const ExportDetailsForm = ({ exportItem }) => {
/>
</SummaryTable.Row>
<SummaryTable.Row
heading="Estimated date for Win"
heading="Estimated date for win"
hideWhenEmpty={false}
>
{isEmpty(exportItem.estimated_win_date)
Expand Down
160 changes: 0 additions & 160 deletions src/client/modules/ExportWins/Details.jsx

This file was deleted.

46 changes: 46 additions & 0 deletions src/client/modules/ExportWins/Details/ResendExportWin.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react'
import Button from '@govuk-react/button'

import { EXPORT_WIN_RESENT__SUCCESS } from '../../../actions'
import multiInstance from '../../../utils/multiinstance'
import { TASK_RESEND_EXPORT_WIN } from './state'
import Task from '../../../components/Task'

const _ResendExportWin = ({ id }) => {
return (
<Task>
{(getTask) => {
const task = getTask(TASK_RESEND_EXPORT_WIN, id)
return (
<Button
disabled={task.progress}
onClick={() => {
task.start({
payload: id,
onSuccessDispatch: EXPORT_WIN_RESENT__SUCCESS,
})
}}
>
Resend export win
</Button>
)
}}
</Task>
)
}

export const ResendExportWin = multiInstance({
name: 'ResendExportWin',
actionPattern: 'EXPORT_WIN_RESENT__',
reducer: (state, action) => {
switch (action.type) {
case EXPORT_WIN_RESENT__SUCCESS:
return {
success: true,
}
default:
return state
}
},
component: _ResendExportWin,
})
168 changes: 168 additions & 0 deletions src/client/modules/ExportWins/Details/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import React from 'react'
import { Link as ReactRouterLink } from 'react-router-dom'
import { SPACING } from '@govuk-react/constants'
import styled from 'styled-components'
import { connect } from 'react-redux'
import { Link } from 'govuk-react'
import pluralize from 'pluralize'

import { DefaultLayout, SummaryTable } from '../../../components'
import ExportWin from '../../../components/Resource/ExportWin'
import { currencyGBP } from '../../../utils/number-utils'
import { formatMediumDate } from '../../../utils/date'
import { ResendExportWin } from './ResendExportWin'
import urls from '../../../../lib/urls'
import { state2props } from './state'

const VerticalSpacer = styled.div`
display: flex;
flex-direction: column;
gap: ${SPACING.SCALE_1};
margin-bottom: ${SPACING.SCALE_5};
`

const NormalFontWeightRow = styled(SummaryTable.Row)`
& th {
font-weight: normal;
}
`

const ExportWinTitle = (props) => (
<ExportWin.Inline {...props}>
{(exportWin) => (
<>
{exportWin.nameOfExport} to {exportWin.country?.name}
</>
)}
</ExportWin.Inline>
)

const groupBreakdowns = (breakdowns) => {
const result =
breakdowns.reduce(
({ groups: groups, totalAmount, yearRange }, breakdown) => {
const group = groups[breakdown.type.name]

return {
totalAmount: totalAmount + breakdown.value,
yearRange: {
min: Math.min(yearRange.min, breakdown.year),
max: Math.max(yearRange.max, breakdown.year),
},
groups: {
...groups,
[breakdown.type.name]: {
yearRange: {
min: Math.min(group?.yearRange.min || Infinity, breakdown.year),
max: Math.max(group?.yearRange.min || 0, breakdown.year),
},
total: (group?.total || 0) + breakdown.value,
},
},
}
},
{
groups: {},
totalAmount: 0,
yearRange: { min: Infinity, max: 0 },
}
) || {}

return {
...result,
totalYears: result.yearRange.max - result.yearRange.min + 1,
}
}

const Detail = (props) => {
const { winId } = props.match.params
const success = props[winId]?.success
const flashMessage = success && { success: ['Successfully sent'] }

return (
<DefaultLayout
heading={<ExportWinTitle id={winId} />}
pageTitle={<ExportWinTitle id={winId} />}
breadcrumbs={[
{
link: urls.dashboard.index(),
text: 'Home',
},
{
link: urls.companies.exportWins.index(),
text: 'Export wins',
},
{ text: <ExportWinTitle id={winId} /> },
]}
flashMessages={flashMessage}
>
<ExportWin id={winId} progressBox={true}>
{(exportWin) => {
const { groups, totalAmount, totalYears } = exportWin
? groupBreakdowns(exportWin.breakdowns)
: {}

return (
<>
<SummaryTable data-test="export-wins-details-table">
<SummaryTable.Row heading="Goods or services">
{exportWin?.goodsVsServices.name}
</SummaryTable.Row>
<SummaryTable.Row heading="Destination country">
{exportWin?.country.name}
</SummaryTable.Row>
{exportWin &&
Object.keys(groups).length > 1 &&
Object.entries(groups).map(([k, { total, yearRange }]) => {
const years = yearRange.max - yearRange.min + 1
return (
<NormalFontWeightRow key={k} heading={k}>
{`${currencyGBP(total)} over ${years} ${pluralize('year', years)}`}
</NormalFontWeightRow>
)
})}
<SummaryTable.Row heading="Total value">
{exportWin &&
`${currencyGBP(totalAmount)} over ${totalYears} ${pluralize('year', totalYears)}`}
</SummaryTable.Row>
<SummaryTable.Row heading="Date won">
{exportWin && formatMediumDate(exportWin.date)}
</SummaryTable.Row>
<SummaryTable.Row heading="Lead officer name">
{exportWin?.leadOfficer.name}
</SummaryTable.Row>
<SummaryTable.Row heading="Comments">
{exportWin?.comments}
</SummaryTable.Row>
<SummaryTable.Row heading="Export win confirmed">
{exportWin &&
(exportWin.isPersonallyConfirmed ? 'Yes' : 'No')}
</SummaryTable.Row>
</SummaryTable>
{exportWin && <ResendExportWin id={exportWin.id} />}
<VerticalSpacer>
{exportWin?.isPersonallyConfirmed && (
<Link
as={ReactRouterLink}
to={urls.companies.exportWins.customerFeedback(winId)}
>
View customer feedback
</Link>
)}
<Link
data-test="export-wins-link"
as={ReactRouterLink}
to={urls.companies.exportWins.index()}
>
Export wins
</Link>
</VerticalSpacer>
</>
)
}}
</ExportWin>
</DefaultLayout>
)
}

export default connect(state2props)(Detail)
3 changes: 3 additions & 0 deletions src/client/modules/ExportWins/Details/state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const TASK_RESEND_EXPORT_WIN = 'TASK_RESEND_EXPORT_WIN'
export const ID = 'ResendExportWin'
export const state2props = (state) => state[ID]
Loading

0 comments on commit 36fe440

Please sign in to comment.