Merged PR 2257: refactor(representations): isolate finalisation boundary helpers (slice R8)
refactor(representations): isolate finalisation boundary helpers (slice R8) Related work items: #22441
This commit is contained in:
@@ -46,6 +46,11 @@ import {
|
||||
resolveInitialCaseDataSources,
|
||||
resolveSubmitCaseDetailsSource
|
||||
} from "./utils/dataResolution";
|
||||
import {
|
||||
buildRepresentationUpdateBody,
|
||||
buildSubmitEnrichedValues,
|
||||
runFinalisationSequence
|
||||
} from "./utils/finalisationBoundary";
|
||||
|
||||
let MakeRepresentation = (props) => {
|
||||
let { t } = useTranslation();
|
||||
@@ -871,24 +876,10 @@ let MakeRepresentation = (props) => {
|
||||
]
|
||||
};
|
||||
|
||||
let updateBody = setRepFileName(formattedValues);
|
||||
|
||||
// Clean and sanitize the body
|
||||
const sanitizedBody = Object.entries(updateBody).reduce(
|
||||
(acc, [key, val]) => {
|
||||
if (val !== null && val !== undefined && !key.startsWith("_")) {
|
||||
acc[key] = val;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
// Normalize "Yes"/"No" to booleans
|
||||
const stringified = JSON.stringify(sanitizedBody)
|
||||
.replace(/:"Yes"/g, ":true")
|
||||
.replace(/:"No"/g, ":false");
|
||||
updateBody = JSON.parse(stringified);
|
||||
const updateBody = buildRepresentationUpdateBody({
|
||||
formattedValues,
|
||||
setRepFileName
|
||||
});
|
||||
|
||||
const sendEmailIfNeeded = () => {
|
||||
if (sendSavedEmail) {
|
||||
@@ -976,23 +967,6 @@ let MakeRepresentation = (props) => {
|
||||
) {
|
||||
const formValues = formObj.representationForm.values;
|
||||
|
||||
const buildSiteAddress = () => {
|
||||
const {
|
||||
pinswg_siteaddressline1,
|
||||
pinswg_siteaddressline2,
|
||||
pinswg_siteaddresstown,
|
||||
pinswg_siteaddresspostcode
|
||||
} = detailsObj;
|
||||
return [
|
||||
pinswg_siteaddressline1,
|
||||
pinswg_siteaddressline2,
|
||||
pinswg_siteaddresstown,
|
||||
pinswg_siteaddresspostcode
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
};
|
||||
|
||||
const representationCapacity =
|
||||
router.query?.state === "edit"
|
||||
? props.props.currentView.representationCapacity
|
||||
@@ -1000,55 +974,19 @@ let MakeRepresentation = (props) => {
|
||||
? "LPA"
|
||||
: values.representationCapacity;
|
||||
|
||||
Object.assign(values, {
|
||||
...formValues,
|
||||
containerID: props.props.accountDetails.containerID,
|
||||
appealType:
|
||||
appealType || caseReferenceObj.repDetails.appealType,
|
||||
incidentID:
|
||||
caseReferenceObj.incidentid ||
|
||||
caseReferenceObj.repDetails.incidentid,
|
||||
caseRef: caseReferenceObj.currentReference,
|
||||
casereference: caseReferenceObj.currentReference,
|
||||
pinswg_questionnaireduedate:
|
||||
detailsObj.pinswg_questionnaireduedate,
|
||||
pinswg_endofrepresentationperiod:
|
||||
detailsObj.pinswg_endofrepresentationperiod,
|
||||
pinswg_applicationacceptedasvalid:
|
||||
detailsObj.pinswg_applicationacceptedasvalid,
|
||||
pinswg_statementduedate: detailsObj.pinswg_statementduedate,
|
||||
pinswg_statementsduedate: detailsObj.pinswg_statementsduedate,
|
||||
pinswg_finalcommentsduedate:
|
||||
detailsObj.pinswg_finalcommentsduedate,
|
||||
pinswg_name: caseReferenceObj.currentReference,
|
||||
firstname: accountDetails.firstname,
|
||||
lastname: accountDetails.lastname,
|
||||
emailAddress: accountDetails.emailaddress1,
|
||||
siteAddress: buildSiteAddress(),
|
||||
pinswg_siteaddressline1: detailsObj.pinswg_siteaddressline1,
|
||||
pinswg_siteaddressline2: detailsObj.pinswg_siteaddressline2,
|
||||
pinswg_siteaddresstown: detailsObj.pinswg_siteaddresstown,
|
||||
pinswg_siteaddresspostcode:
|
||||
detailsObj.pinswg_siteaddresspostcode,
|
||||
pinswg_lpareference: resultsObj?.pinswg_lpareference,
|
||||
_pinswg_appellant_value: detailsObj._pinswg_appellant_value,
|
||||
"_pinswg_appellant_value@OData.Community.Display.V1.FormattedValue":
|
||||
detailsObj[
|
||||
"_pinswg_appellant_value@OData.Community.Display.V1.FormattedValue"
|
||||
],
|
||||
_pinswg_localplanningauthority_value:
|
||||
detailsObj._pinswg_localplanningauthority_value ||
|
||||
detailsObj._pinswg_associatedlpa_value,
|
||||
"_pinswg_localplanningauthority_value@OData.Community.Display.V1.FormattedValue":
|
||||
detailsObj[
|
||||
"_pinswg_localplanningauthority_value@OData.Community.Display.V1.FormattedValue"
|
||||
] ||
|
||||
detailsObj[
|
||||
"_pinswg_associatedlpa_value@OData.Community.Display.V1.FormattedValue"
|
||||
],
|
||||
representationCapacity,
|
||||
locale: router.locale
|
||||
});
|
||||
Object.assign(
|
||||
values,
|
||||
buildSubmitEnrichedValues({
|
||||
formValues,
|
||||
accountDetails,
|
||||
appealType,
|
||||
caseReferenceObj,
|
||||
detailsObj,
|
||||
resultsObj,
|
||||
representationCapacity,
|
||||
locale: router.locale
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const shouldSubmit = !currentView.representationSubmit;
|
||||
@@ -1102,19 +1040,19 @@ let MakeRepresentation = (props) => {
|
||||
}
|
||||
|
||||
// Final PDF & upload
|
||||
setFinaliseAppealProcess(true);
|
||||
generateRepPDF(
|
||||
runFinalisationSequence({
|
||||
values,
|
||||
props.props.accountDetails.containerID,
|
||||
props.currentView.caseReference.currentReference
|
||||
).then((data) => {
|
||||
containerID: props.props.accountDetails.containerID,
|
||||
currentReference:
|
||||
props.currentView.caseReference.currentReference,
|
||||
setFinaliseAppealProcess,
|
||||
generateRepPDF,
|
||||
updateLinks,
|
||||
uploadRepresentationFiles,
|
||||
setRepresentationSubmit,
|
||||
setRepresentationSubmitConfirmation
|
||||
}).then((data) => {
|
||||
console.log(data, "");
|
||||
if (data.status === "success") {
|
||||
values = updateLinks(values);
|
||||
uploadRepresentationFiles(values);
|
||||
setRepresentationSubmit(true);
|
||||
setRepresentationSubmitConfirmation(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
export const buildRepresentationUpdateBody = ({
|
||||
formattedValues,
|
||||
setRepFileName
|
||||
}) => {
|
||||
let updateBody = setRepFileName(formattedValues);
|
||||
|
||||
const sanitizedBody = Object.entries(updateBody).reduce(
|
||||
(acc, [key, val]) => {
|
||||
if (val !== null && val !== undefined && !key.startsWith("_")) {
|
||||
acc[key] = val;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
const stringified = JSON.stringify(sanitizedBody)
|
||||
.replace(/:"Yes"/g, ":true")
|
||||
.replace(/:"No"/g, ":false");
|
||||
|
||||
updateBody = JSON.parse(stringified);
|
||||
|
||||
return updateBody;
|
||||
};
|
||||
|
||||
export const buildSubmitEnrichedValues = ({
|
||||
formValues,
|
||||
accountDetails,
|
||||
appealType,
|
||||
caseReferenceObj,
|
||||
detailsObj,
|
||||
resultsObj,
|
||||
representationCapacity,
|
||||
locale
|
||||
}) => {
|
||||
const buildSiteAddress = () => {
|
||||
const {
|
||||
pinswg_siteaddressline1,
|
||||
pinswg_siteaddressline2,
|
||||
pinswg_siteaddresstown,
|
||||
pinswg_siteaddresspostcode
|
||||
} = detailsObj;
|
||||
|
||||
return [
|
||||
pinswg_siteaddressline1,
|
||||
pinswg_siteaddressline2,
|
||||
pinswg_siteaddresstown,
|
||||
pinswg_siteaddresspostcode
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
};
|
||||
|
||||
return {
|
||||
...formValues,
|
||||
containerID: accountDetails.containerID,
|
||||
appealType: appealType || caseReferenceObj.repDetails.appealType,
|
||||
incidentID:
|
||||
caseReferenceObj.incidentid ||
|
||||
caseReferenceObj.repDetails.incidentid,
|
||||
caseRef: caseReferenceObj.currentReference,
|
||||
casereference: caseReferenceObj.currentReference,
|
||||
pinswg_questionnaireduedate: detailsObj.pinswg_questionnaireduedate,
|
||||
pinswg_endofrepresentationperiod:
|
||||
detailsObj.pinswg_endofrepresentationperiod,
|
||||
pinswg_applicationacceptedasvalid:
|
||||
detailsObj.pinswg_applicationacceptedasvalid,
|
||||
pinswg_statementduedate: detailsObj.pinswg_statementduedate,
|
||||
pinswg_statementsduedate: detailsObj.pinswg_statementsduedate,
|
||||
pinswg_finalcommentsduedate: detailsObj.pinswg_finalcommentsduedate,
|
||||
pinswg_name: caseReferenceObj.currentReference,
|
||||
firstname: accountDetails.firstname,
|
||||
lastname: accountDetails.lastname,
|
||||
emailAddress: accountDetails.emailaddress1,
|
||||
siteAddress: buildSiteAddress(),
|
||||
pinswg_siteaddressline1: detailsObj.pinswg_siteaddressline1,
|
||||
pinswg_siteaddressline2: detailsObj.pinswg_siteaddressline2,
|
||||
pinswg_siteaddresstown: detailsObj.pinswg_siteaddresstown,
|
||||
pinswg_siteaddresspostcode: detailsObj.pinswg_siteaddresspostcode,
|
||||
pinswg_lpareference: resultsObj?.pinswg_lpareference,
|
||||
_pinswg_appellant_value: detailsObj._pinswg_appellant_value,
|
||||
"_pinswg_appellant_value@OData.Community.Display.V1.FormattedValue":
|
||||
detailsObj[
|
||||
"_pinswg_appellant_value@OData.Community.Display.V1.FormattedValue"
|
||||
],
|
||||
_pinswg_localplanningauthority_value:
|
||||
detailsObj._pinswg_localplanningauthority_value ||
|
||||
detailsObj._pinswg_associatedlpa_value,
|
||||
"_pinswg_localplanningauthority_value@OData.Community.Display.V1.FormattedValue":
|
||||
detailsObj[
|
||||
"_pinswg_localplanningauthority_value@OData.Community.Display.V1.FormattedValue"
|
||||
] ||
|
||||
detailsObj[
|
||||
"_pinswg_associatedlpa_value@OData.Community.Display.V1.FormattedValue"
|
||||
],
|
||||
representationCapacity,
|
||||
locale
|
||||
};
|
||||
};
|
||||
|
||||
export const runFinalisationSequence = ({
|
||||
values,
|
||||
containerID,
|
||||
currentReference,
|
||||
setFinaliseAppealProcess,
|
||||
generateRepPDF,
|
||||
updateLinks,
|
||||
uploadRepresentationFiles,
|
||||
setRepresentationSubmit,
|
||||
setRepresentationSubmitConfirmation
|
||||
}) => {
|
||||
setFinaliseAppealProcess(true);
|
||||
|
||||
return generateRepPDF(values, containerID, currentReference).then(
|
||||
(data) => {
|
||||
if (data.status === "success") {
|
||||
const updatedValues = updateLinks(values);
|
||||
uploadRepresentationFiles(updatedValues);
|
||||
setRepresentationSubmit(true);
|
||||
setRepresentationSubmitConfirmation(true);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -321,6 +321,29 @@ Isolate submission logic.
|
||||
**Risk Level:** HIGH
|
||||
(Must only be done after earlier slices stabilised)
|
||||
|
||||
**Completion notes (this slice):**
|
||||
|
||||
- Implemented on feature branch created from `refactor`: `rep-slice-r8-finalisation-boundary`.
|
||||
- Added a small representation-specific helper module:
|
||||
- `components/case/representation/utils/finalisationBoundary.js`
|
||||
- Extracted only approved R8 seams:
|
||||
- `buildRepresentationUpdateBody(...)` (pure shaping)
|
||||
- `buildSubmitEnrichedValues(...)` (pure shaping)
|
||||
- `runFinalisationSequence(...)` (ultra-thin orchestration wrapper)
|
||||
- Wired `components/case/representation/index.js` to use the new helpers while preserving parent-owned business branching.
|
||||
- Explicitly preserved R8 constraints:
|
||||
- no completion-side-effect extraction from `representationComplete.js`
|
||||
- no route/query changes
|
||||
- no payload contract changes
|
||||
- no validation logic changes
|
||||
- no file upload/PDF/email behaviour changes
|
||||
- no sequencing drift in finalisation success path
|
||||
|
||||
**Validation evidence:**
|
||||
|
||||
- `npm run lint` completed (warnings only, no new errors).
|
||||
- `npm run test:reps` completed: **7 passed (4.4m)**.
|
||||
|
||||
---
|
||||
|
||||
## Rules
|
||||
|
||||
Reference in New Issue
Block a user