src/applications/ivc-champva/10-10D/config/submitTransformer.js
import { transformForSubmit as formsSystemTransformForSubmit } from 'platform/forms-system/src/js/helpers';
import { FILE_UPLOAD_ORDER } from './constants';
import {
adjustYearString,
concatStreets,
getAgeInYears,
} from '../../shared/utilities';
// Rearranges date string from YYYY-MM-DD to MM-DD-YYYY
function fmtDate(date) {
return date?.length && date.length === 10
? `${date.slice(5)}-${date.slice(0, 4)}`
: date;
}
// Returns list of object keys where obj[key] === true. Used
// to get the list of relationships a certifier has w/ the applicants:
function trueKeysOnly(obj) {
return Object.keys(obj ?? {}).filter(k => obj[k] === true);
}
// Simplify a relationship object from (potentially) multiple nested objects to a single string
function transformRelationship(obj) {
if (typeof obj === 'string') return obj;
let rel = obj?.relationshipToVeteran;
// Check if relationshipToVeteran is an object
if (typeof obj?.relationshipToVeteran === 'object') {
// Iterate over keys in relationshipToVeteran object
Object.keys(obj?.relationshipToVeteran).forEach(key => {
// edge case for certifier relationship (generated by a checkboxgroup):
if (obj?.relationshipToVeteran[key] === true) {
rel = key; // e.g., `'spouse': true` yields `'spouse'`
}
});
}
// Check if otherRelationshipToVeteran is a string
if (typeof obj?.otherRelationshipToVeteran === 'string') {
rel = obj?.otherRelationshipToVeteran;
}
return rel;
}
// For each applicant, adjust organization of the object, add supporting documents array
function transformApplicants(applicants) {
const applicantsPostTransform = [];
applicants.forEach(app => {
let transformedApp = {
...app,
ssnOrTin: app.applicantSSN?.ssn ?? '',
vetRelationship: transformRelationship(
app.applicantRelationshipToSponsor || 'NA',
),
// Grab any file upload properties from this applicant and combine into a
// supporting documents array:
applicantSupportingDocuments: FILE_UPLOAD_ORDER.map(
property => app?.[property],
).filter(el => el), // Drop any undefineds/nulls
};
transformedApp = adjustYearString(transformedApp);
transformedApp.applicantAddress = concatStreets(
transformedApp.applicantAddress,
);
applicantsPostTransform.push(transformedApp);
});
return applicantsPostTransform;
}
export default function transformForSubmit(formConfig, form) {
const transformedData = JSON.parse(
formsSystemTransformForSubmit(formConfig, form),
);
if (transformedData.sponsorAddress)
transformedData.sponsorAddress = concatStreets(
transformedData.sponsorAddress,
);
if (transformedData.certifierAddress)
transformedData.certifierAddress = concatStreets(
transformedData.certifierAddress,
);
const currentDate =
fmtDate(new Date().toISOString().replace(/T.*/, '')) || '';
const dataPostTransform = {
veteran: {
fullName: transformedData?.veteransFullName || {},
ssnOrTin: transformedData?.ssn?.ssn || '',
vaClaimNumber: transformedData?.ssn?.vaFileNumber || '',
dateOfBirth: fmtDate(transformedData?.sponsorDob) || '',
phoneNumber: transformedData?.sponsorPhone || '',
address: transformedData?.sponsorAddress || {},
sponsorIsDeceased: transformedData?.sponsorIsDeceased,
dateOfDeath: fmtDate(transformedData?.sponsorDOD) || '',
// Find the first applicant with a date of marriage to sponsor
dateOfMarriage:
fmtDate(
transformedData?.applicants?.find(
a =>
a?.applicantRelationshipToSponsor?.relationshipToVeteran ===
'spouse' && a?.dateOfMarriageToSponsor !== undefined,
)?.dateOfMarriageToSponsor,
) || '',
isActiveServiceDeath: transformedData?.sponsorDeathConditions,
},
applicants: transformApplicants(transformedData.applicants ?? []),
// If certifier is also applicant, we don't need to fill out the
// bottom "Certification" section of the PDF:
certification:
transformedData?.certifierRole === 'applicant'
? { date: currentDate }
: {
date: currentDate,
lastName: transformedData?.certifierName?.last || '',
middleInitial: transformedData?.certifierName?.middle || '',
firstName: transformedData?.certifierName?.first || '',
phoneNumber: transformedData?.certifierPhone || '',
// will produce string list of checkboxgroup keys (e.g., "spouse; child")
relationship: trueKeysOnly(
transformedData?.certifierRelationship?.relationshipToVeteran,
).join('; '),
streetAddress:
transformedData?.certifierAddress?.streetCombined || '',
city: transformedData?.certifierAddress?.city || '',
state: transformedData?.certifierAddress?.state || '',
postalCode: transformedData?.certifierAddress?.postalCode || '',
},
supportingDocs: [],
// Include everything we originally received
rawData: transformedData,
};
// Flatten supporting docs for all applicants to a single array
const supDocs = [];
dataPostTransform.applicants.forEach(app => {
if (app.applicantSupportingDocuments.length > 0) {
app.applicantSupportingDocuments.forEach(doc => {
if (doc !== undefined && doc !== null) {
// doc is an array of files for a given input (e.g., insurance cards).
// For clarity's sake, add applicant's name onto each file object:
const files = doc.map(file => ({
...file,
applicantName: app.applicantName,
}));
supDocs.push(...files);
}
});
}
});
// Set a top-level boolean indicating if any applicants are over 65
dataPostTransform.hasApplicantOver65 = dataPostTransform.applicants.some(
app => getAgeInYears(app.applicantDob) >= 65,
);
dataPostTransform.supportingDocs = dataPostTransform.supportingDocs
.flat()
.concat(supDocs);
dataPostTransform.certifierRole = transformedData.certifierRole;
dataPostTransform.statementOfTruthSignature =
transformedData.statementOfTruthSignature;
// `primaryContactInfo` is who BE callback API emails if there's a notification event
dataPostTransform.primaryContactInfo = {
name: transformedData.certifierName,
email: transformedData.certifierEmail,
phone: transformedData.certifierPhone,
};
return JSON.stringify({
...dataPostTransform,
formNumber: formConfig.formId,
});
}