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,
|
resolveInitialCaseDataSources,
|
||||||
resolveSubmitCaseDetailsSource
|
resolveSubmitCaseDetailsSource
|
||||||
} from "./utils/dataResolution";
|
} from "./utils/dataResolution";
|
||||||
|
import {
|
||||||
|
buildRepresentationUpdateBody,
|
||||||
|
buildSubmitEnrichedValues,
|
||||||
|
runFinalisationSequence
|
||||||
|
} from "./utils/finalisationBoundary";
|
||||||
|
|
||||||
let MakeRepresentation = (props) => {
|
let MakeRepresentation = (props) => {
|
||||||
let { t } = useTranslation();
|
let { t } = useTranslation();
|
||||||
@@ -871,24 +876,10 @@ let MakeRepresentation = (props) => {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
let updateBody = setRepFileName(formattedValues);
|
const updateBody = buildRepresentationUpdateBody({
|
||||||
|
formattedValues,
|
||||||
// Clean and sanitize the body
|
setRepFileName
|
||||||
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 sendEmailIfNeeded = () => {
|
const sendEmailIfNeeded = () => {
|
||||||
if (sendSavedEmail) {
|
if (sendSavedEmail) {
|
||||||
@@ -976,23 +967,6 @@ let MakeRepresentation = (props) => {
|
|||||||
) {
|
) {
|
||||||
const formValues = formObj.representationForm.values;
|
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 =
|
const representationCapacity =
|
||||||
router.query?.state === "edit"
|
router.query?.state === "edit"
|
||||||
? props.props.currentView.representationCapacity
|
? props.props.currentView.representationCapacity
|
||||||
@@ -1000,55 +974,19 @@ let MakeRepresentation = (props) => {
|
|||||||
? "LPA"
|
? "LPA"
|
||||||
: values.representationCapacity;
|
: values.representationCapacity;
|
||||||
|
|
||||||
Object.assign(values, {
|
Object.assign(
|
||||||
...formValues,
|
values,
|
||||||
containerID: props.props.accountDetails.containerID,
|
buildSubmitEnrichedValues({
|
||||||
appealType:
|
formValues,
|
||||||
appealType || caseReferenceObj.repDetails.appealType,
|
accountDetails,
|
||||||
incidentID:
|
appealType,
|
||||||
caseReferenceObj.incidentid ||
|
caseReferenceObj,
|
||||||
caseReferenceObj.repDetails.incidentid,
|
detailsObj,
|
||||||
caseRef: caseReferenceObj.currentReference,
|
resultsObj,
|
||||||
casereference: caseReferenceObj.currentReference,
|
representationCapacity,
|
||||||
pinswg_questionnaireduedate:
|
locale: router.locale
|
||||||
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
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const shouldSubmit = !currentView.representationSubmit;
|
const shouldSubmit = !currentView.representationSubmit;
|
||||||
@@ -1102,19 +1040,19 @@ let MakeRepresentation = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Final PDF & upload
|
// Final PDF & upload
|
||||||
setFinaliseAppealProcess(true);
|
runFinalisationSequence({
|
||||||
generateRepPDF(
|
|
||||||
values,
|
values,
|
||||||
props.props.accountDetails.containerID,
|
containerID: props.props.accountDetails.containerID,
|
||||||
props.currentView.caseReference.currentReference
|
currentReference:
|
||||||
).then((data) => {
|
props.currentView.caseReference.currentReference,
|
||||||
|
setFinaliseAppealProcess,
|
||||||
|
generateRepPDF,
|
||||||
|
updateLinks,
|
||||||
|
uploadRepresentationFiles,
|
||||||
|
setRepresentationSubmit,
|
||||||
|
setRepresentationSubmitConfirmation
|
||||||
|
}).then((data) => {
|
||||||
console.log(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
|
**Risk Level:** HIGH
|
||||||
(Must only be done after earlier slices stabilised)
|
(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
|
## Rules
|
||||||
|
|||||||
Reference in New Issue
Block a user