@@ -16,6 +16,7 @@ import { format as dateFormat } from '~/src/helpers/date.js'
1616import { stringHasNonEmptyValue } from '~/src/helpers/string-utils.js'
1717import { escapeContent , escapeFileLabel } from '~/src/lib/notify.js'
1818import {
19+ extractPaymentDetails ,
1920 findRepeaterPageByKey ,
2021 formatLocationField ,
2122 formatMultilineTextField ,
@@ -38,55 +39,37 @@ export function handleReferenceNumber(definition, message, lines) {
3839}
3940
4041/**
41- * Human readable notify formatter v1
42+ * Appends the payment details section to the email lines if payment exists
4243 * @param {FormAdapterSubmissionMessage } formSubmissionMessage
43- * @param {FormDefinition } formDefinition
44- * @param {string } _schemaVersion
44+ * @param {string[] } lines
4545 */
46- export function formatter (
47- formSubmissionMessage ,
48- formDefinition ,
49- _schemaVersion
50- ) {
51- const { meta, result } = formSubmissionMessage
52- const { isPreview, status } = meta
53- const files = result . files
46+ function appendPaymentSection ( formSubmissionMessage , lines ) {
47+ const paymentDetails = extractPaymentDetails ( formSubmissionMessage )
5448
55- const formModel = new FormModel ( formDefinition , { basePath : '' } , { } )
56-
57- const formName = escapeContent ( meta . formName )
58- /**
59- * @todo Refactor this below but the code to
60- * generate the question and answers works for now
61- */
62- const now = new Date ( )
63- const formattedNow = `${ dateFormat ( now , 'h:mmaaa' ) } on ${ dateFormat ( now , 'd MMMM yyyy' ) } `
64-
65- const fileExpiryDate = addDays ( now , FILE_EXPIRY_OFFSET )
66- const formattedExpiryDate = `${ dateFormat ( fileExpiryDate , 'h:mmaaa' ) } on ${ dateFormat ( fileExpiryDate , 'eeee d MMMM yyyy' ) } `
67-
68- const order = calculateOrder ( formDefinition , formSubmissionMessage )
69- const componentMap = new Map ( )
70- /**
71- * @type {string[] }
72- */
73- const lines = [ ]
74-
75- lines . push (
76- `^ For security reasons, the links in this email expire at ${ escapeContent ( formattedExpiryDate ) } \n`
77- )
78-
79- if ( isPreview ) {
80- lines . push ( `This is a test of the ${ formName } ${ status } form.\n` )
49+ if ( ! paymentDetails ) {
50+ return
8151 }
8252
8353 lines . push (
84- `${ formName } form received at ${ escapeContent ( formattedNow ) } .\n` ,
54+ '---\n' ,
55+ '# Payment details\n' ,
56+ '## Payment for\n' ,
57+ `${ escapeContent ( paymentDetails . description ) } \n` ,
58+ '## Total amount\n' ,
59+ `£${ paymentDetails . amount } \n` ,
60+ '## Date of payment\n' ,
61+ `${ escapeContent ( paymentDetails . dateOfPayment ) } \n` ,
8562 '---\n'
8663 )
64+ }
8765
88- handleReferenceNumber ( formDefinition , formSubmissionMessage , lines )
89-
66+ /**
67+ * Process main form entries and add them to the component map
68+ * @param {FormAdapterSubmissionMessage } formSubmissionMessage
69+ * @param {FormModel } formModel
70+ * @param {Map<string, string[]> } componentMap
71+ */
72+ function processMainEntries ( formSubmissionMessage , formModel , componentMap ) {
9073 const mainEntries = Object . entries ( {
9174 ...formSubmissionMessage . data . main ,
9275 ...formSubmissionMessage . data . files
@@ -115,44 +98,123 @@ export function formatter(
11598 questionLines . push ( '---\n' )
11699 componentMap . set ( key , questionLines )
117100 }
101+ }
118102
103+ /**
104+ * Process repeater entries and add them to the component map
105+ * @param {FormAdapterSubmissionMessage } formSubmissionMessage
106+ * @param {FormDefinition } formDefinition
107+ * @param {Map<string, string[]> } componentMap
108+ */
109+ function processRepeaterEntries (
110+ formSubmissionMessage ,
111+ formDefinition ,
112+ componentMap
113+ ) {
119114 const repeaterEntries = Object . entries (
120115 formSubmissionMessage . result . files . repeaters
121116 )
122117
123118 for ( const [ key , fileId ] of repeaterEntries ) {
124119 const repeaterPage = findRepeaterPageByKey ( key , formDefinition )
125120
126- const questionLines = /** @type {string[] } */ ( [ ] )
121+ if ( ! hasRepeater ( repeaterPage ) ) {
122+ continue
123+ }
127124
128- if ( hasRepeater ( repeaterPage ) ) {
129- const label = escapeContent ( repeaterPage . repeat . options . title )
130- const componentKey = repeaterPage . repeat . options . name
125+ const label = escapeContent ( repeaterPage . repeat . options . title )
126+ const componentKey = repeaterPage . repeat . options . name
127+ const questionLines = /** @type { string[] } */ ( [ ] )
131128
132- questionLines . push ( `## ${ label } \n` )
129+ questionLines . push ( `## ${ label } \n` )
133130
134- const repeaterFilename = escapeFileLabel ( `Download ${ label } (CSV)` )
135- questionLines . push (
136- `[${ repeaterFilename } ](${ designerUrl } /file-download/${ fileId } )\n` ,
137- '---\n'
138- )
139- componentMap . set ( componentKey , questionLines )
140- }
131+ const repeaterFilename = escapeFileLabel ( `Download ${ label } (CSV)` )
132+ questionLines . push (
133+ `[${ repeaterFilename } ](${ designerUrl } /file-download/${ fileId } )\n` ,
134+ '---\n'
135+ )
136+ componentMap . set ( componentKey , questionLines )
141137 }
138+ }
142139
140+ /**
141+ * Append component lines to the output in the correct order
142+ * @param {string[] } order
143+ * @param {Map<string, string[]> } componentMap
144+ * @param {string[] } lines
145+ */
146+ function appendComponentLines ( order , componentMap , lines ) {
143147 for ( const key of order ) {
144148 const componentLines = componentMap . get ( key )
145149
146150 if ( componentLines ) {
147151 lines . push ( ...componentLines )
148152 }
149153 }
154+ }
155+
156+ /**
157+ * Human readable notify formatter v1
158+ * @param {FormAdapterSubmissionMessage } formSubmissionMessage
159+ * @param {FormDefinition } formDefinition
160+ * @param {string } _schemaVersion
161+ */
162+ export function formatter (
163+ formSubmissionMessage ,
164+ formDefinition ,
165+ _schemaVersion
166+ ) {
167+ const { meta, result } = formSubmissionMessage
168+ const { isPreview, status } = meta
169+ const files = result . files
170+
171+ const formModel = new FormModel ( formDefinition , { basePath : '' } , { } )
172+
173+ const formName = escapeContent ( meta . formName )
174+ /**
175+ * @todo Refactor this below but the code to
176+ * generate the question and answers works for now
177+ */
178+ const now = new Date ( )
179+ const formattedNow = `${ dateFormat ( now , 'h:mmaaa' ) } on ${ dateFormat ( now , 'd MMMM yyyy' ) } `
180+
181+ const fileExpiryDate = addDays ( now , FILE_EXPIRY_OFFSET )
182+ const formattedExpiryDate = `${ dateFormat ( fileExpiryDate , 'h:mmaaa' ) } on ${ dateFormat ( fileExpiryDate , 'eeee d MMMM yyyy' ) } `
183+
184+ const order = calculateOrder ( formDefinition , formSubmissionMessage )
185+ const componentMap = new Map ( )
186+ /**
187+ * @type {string[] }
188+ */
189+ const lines = [ ]
190+
191+ lines . push (
192+ `^ For security reasons, the links in this email expire at ${ escapeContent ( formattedExpiryDate ) } \n`
193+ )
194+
195+ if ( isPreview ) {
196+ lines . push ( `This is a test of the ${ formName } ${ status } form.\n` )
197+ }
198+
199+ lines . push (
200+ `${ formName } form received at ${ escapeContent ( formattedNow ) } .\n` ,
201+ '---\n'
202+ )
203+
204+ handleReferenceNumber ( formDefinition , formSubmissionMessage , lines )
205+
206+ processMainEntries ( formSubmissionMessage , formModel , componentMap )
207+ processRepeaterEntries ( formSubmissionMessage , formDefinition , componentMap )
208+ appendComponentLines ( order , componentMap , lines )
150209
151210 const mainResultFilename = escapeFileLabel ( 'Download main form (CSV)' )
152211 lines . push (
153212 `[${ mainResultFilename } ](${ designerUrl } /file-download/${ files . main } )\n`
154213 )
155214
215+ // Add payment details section if payment exists
216+ appendPaymentSection ( formSubmissionMessage , lines )
217+
156218 lines . push ( '\n' , 'Thanks,' , 'Defra' )
157219
158220 return lines . join ( '\n' )
0 commit comments