diff --git a/app/client/src/config.tsx b/app/client/src/config.tsx index c7cb4380..64a8ff1e 100644 --- a/app/client/src/config.tsx +++ b/app/client/src/config.tsx @@ -64,35 +64,76 @@ export const messages = { /** * Formio status mapping for all form submissions (practically, just capitalizes - * "draft" or "submitted", but follows same format as BAP status maps). + * "draft" or "submitted", but follows same format as BAP status map). */ export const formioStatusMap = new Map() .set("draft", "Draft") .set("submitted", "Submitted"); /** - * BAP internal to external status mapping for FRF submissions. + * BAP internal to external status mapping by year and form type. */ -export const bapFRFStatusMap = new Map() - .set("Needs Clarification", "Needs Clarification") - .set("Withdrawn", "Withdrawn") - .set("Coordinator Denied", "Not Selected") - .set("Accepted", "Selected"); +export const bapStatusMap = { + 2022: { + frf: new Map() + .set("Needs Clarification", "Needs Clarification") + .set("Withdrawn", "Withdrawn") + .set("Coordinator Denied", "Not Selected") + .set("Accepted", "Selected"), + prf: new Map() + .set("Needs Clarification", "Needs Clarification") + .set("Withdrawn", "Withdrawn") + .set("Coordinator Denied", "Funding Not Approved") + .set("Accepted", "Funding Approved"), + crf: new Map() + .set("Needs Clarification", "Needs Clarification") + .set("Reimbursement Needed", "Reimbursement Needed") + .set("Branch Director Denied", "Close Out Not Approved") + .set("Branch Director Approved", "Close Out Approved"), + }, + 2023: { + frf: new Map() + .set("Needs Clarification", "Needs Clarification") + .set("Withdrawn", "Withdrawn") + .set("Coordinator Denied", "Not Selected") + .set("Accepted", "Selected"), + prf: new Map() + .set("Needs Clarification", "Needs Clarification") + .set("Withdrawn", "Withdrawn") + .set("Coordinator Denied", "Funding Denied") + .set("Accepted", "Funding Approved"), + crf: new Map(), + }, +}; /** - * BAP internal to external status mapping for PRF submissions. + * Formio user name field by year and form type. */ -export const bapPRFStatusMap = new Map() - .set("Needs Clarification", "Needs Clarification") - .set("Withdrawn", "Withdrawn") - .set("Coordinator Denied", "Funding Not Approved") - .set("Accepted", "Funding Approved"); +export const formioNameField = { + 2022: { + frf: "sam_hidden_applicant_name", + prf: "applicantName", + crf: "signatureName", + }, + 2023: { + frf: "_bap_applicant_name", + prf: "", + crf: "", + }, +}; /** - * BAP internal to external status mapping for CRF submissions. + * Formio user email field by year and form type. */ -export const bapCRFStatusMap = new Map() - .set("Needs Clarification", "Needs Clarification") - .set("Reimbursement Needed", "Reimbursement Needed") - .set("Branch Director Denied", "Close Out Not Approved") - .set("Branch Director Approved", "Close Out Approved"); +export const formioEmailField = { + 2022: { + frf: "last_updated_by", + prf: "hidden_current_user_email", + crf: "hidden_current_user_email", + }, + 2023: { + frf: "_user_email", + prf: "", + crf: "", + }, +}; diff --git a/app/client/src/routes/helpdesk.tsx b/app/client/src/routes/helpdesk.tsx index 2ce12296..54b80d50 100644 --- a/app/client/src/routes/helpdesk.tsx +++ b/app/client/src/routes/helpdesk.tsx @@ -10,9 +10,9 @@ import { serverUrl, messages, formioStatusMap, - bapFRFStatusMap, - bapPRFStatusMap, - bapCRFStatusMap, + bapStatusMap, + formioNameField, + formioEmailField, } from "@/config"; import { type FormType, @@ -80,49 +80,17 @@ function ResultTableRows(props: { const bapInternalStatus = bap.status || ""; const formioStatus = formioStatusMap.get(formio.state); - /* TODO: update logic once BAP supports 2023 FRF */ - - const id = - rebateYear === "2023" - ? formio._id - : lastSearchedText.length === 6 - ? bap.rebateId - : bap.mongoId; - - const status = - rebateYear === "2023" - ? formioStatus - : submissionNeedsEdits({ formio, bap }) - ? "Edits Requested" - : formType === "frf" - ? bapFRFStatusMap.get(bapInternalStatus) || formioStatus - : formType === "prf" - ? bapPRFStatusMap.get(bapInternalStatus) || formioStatus - : formType === "crf" - ? bapCRFStatusMap.get(bapInternalStatus) || formioStatus - : ""; - - const name = - rebateYear === "2023" - ? (formio as FormioFRF2023Submission).data._bap_applicant_name - : formType === "frf" - ? (formio as FormioFRF2022Submission).data.sam_hidden_applicant_name - : formType === "prf" - ? (formio as FormioPRF2022Submission).data.applicantName - : formType === "crf" - ? (formio as FormioCRF2022Submission).data.signatureName - : ""; - - const email = - rebateYear === "2023" - ? (formio as FormioFRF2023Submission).data._user_email - : formType === "frf" - ? (formio as FormioFRF2022Submission).data.last_updated_by - : formType === "prf" - ? (formio as FormioPRF2022Submission).data.hidden_current_user_email - : formType === "crf" - ? (formio as FormioCRF2022Submission).data.hidden_current_user_email - : ""; + const id = lastSearchedText.length === 6 ? bap.rebateId : bap.mongoId; + + const status = submissionNeedsEdits({ formio, bap }) + ? "Edits Requested" + : bapStatusMap[rebateYear][formType].get(bapInternalStatus) || formioStatus; + + const nameField = formioNameField[rebateYear][formType]; + const emailField = formioEmailField[rebateYear][formType]; + + const name = (formio.data[nameField] as string) || ""; + const email = (formio.data[emailField] as string) || ""; return ( <> @@ -204,7 +172,11 @@ export function Helpdesk() { "tw-rounded-md tw-border-0 tw-text-sm tw-font-bold tw-leading-4 tw-ring-1 tw-ring-inset tw-ring-gray-300", )} name="rebate-year" - onChange={(ev) => setRebateYear(ev.target.value as RebateYear)} + onChange={(ev) => { + setRebateYear(ev.target.value as RebateYear); + setResultDisplayed(false); + queryClient.resetQueries({ queryKey: ["helpdesk"] }); + }} defaultValue={rebateYear} > diff --git a/app/server/app/routes/help.js b/app/server/app/routes/help.js index 9ac26e78..d58f40ca 100644 --- a/app/server/app/routes/help.js +++ b/app/server/app/routes/help.js @@ -36,19 +36,32 @@ router.get("/formio/:rebateYear/:formType/:id", (req, res) => { const formioFormUrl = formUrl[rebateYear][formType]; - /** - * TODO: revisit `getBapFormSubmissionData()` to include rebateYear once BAP - * supports 2023 FRF - */ - if (rebateYear === "2023") { - if (rebateId && !mongoId) { + return getBapFormSubmissionData({ + rebateYear, + formType, + rebateId, + mongoId, + req, + }).then((bapSubmission) => { + if (!bapSubmission || !formioFormUrl) { + const logId = rebateId || mongoId; const errorStatus = 500; - const errorMessage = `Error getting 2023 ${formName} submission '${rebateId}'.`; + const errorMessage = `Error getting ${rebateYear} ${formName} submission '${logId}' from the BAP.`; return res.status(errorStatus).json({ message: errorMessage }); } + const { + UEI_EFTI_Combo_Key__c, + CSB_Form_ID__c, + CSB_Modified_Full_String__c, + CSB_Review_Item_ID__c, + Parent_Rebate_ID__c, + Record_Type_Name__c, + Parent_CSB_Rebate__r, + } = bapSubmission; + return Promise.all([ - axiosFormio(req).get(`${formioFormUrl}/submission/${mongoId}`), + axiosFormio(req).get(`${formioFormUrl}/submission/${CSB_Form_ID__c}`), axiosFormio(req).get(formioFormUrl), ]) .then((responses) => responses.map((axiosRes) => axiosRes.data)) @@ -57,76 +70,28 @@ router.get("/formio/:rebateYear/:formType/:id", (req, res) => { formSchema: { url: formioFormUrl, json: schema }, formio: formioSubmission, bap: { - modified: null, - comboKey: null, - mongoId: null, - rebateId: null, - reviewItemId: null, - status: null, + modified: CSB_Modified_Full_String__c, // ISO 8601 date time string + comboKey: UEI_EFTI_Combo_Key__c, // UEI + EFTI combo key + mongoId: CSB_Form_ID__c, // MongoDB Object ID + rebateId: Parent_Rebate_ID__c, // CSB Rebate ID (6 digits) + reviewItemId: CSB_Review_Item_ID__c, // CSB Rebate ID with form/version ID (9 digits) + status: Record_Type_Name__c.startsWith("CSB Funding Request") + ? Parent_CSB_Rebate__r?.CSB_Funding_Request_Status__c + : Record_Type_Name__c.startsWith("CSB Payment Request") + ? Parent_CSB_Rebate__r?.CSB_Payment_Request_Status__c + : Record_Type_Name__c.startsWith("CSB Close Out Request") + ? Parent_CSB_Rebate__r?.CSB_Closeout_Request_Status__c + : "", }, }); }) .catch((error) => { // NOTE: error is logged in axiosFormio response interceptor const errorStatus = error.response?.status || 500; - const errorMessage = `Error getting ${rebateYear} ${formName} submission '${mongoId}'.`; + const errorMessage = `Error getting ${rebateYear} ${formName} submission '${CSB_Form_ID__c}'.`; return res.status(errorStatus).json({ message: errorMessage }); }); - } - - return getBapFormSubmissionData(req, formType, rebateId, mongoId).then( - (bapSubmission) => { - if (!bapSubmission || !formioFormUrl) { - const logId = rebateId || mongoId; - const errorStatus = 500; - const errorMessage = `Error getting ${rebateYear} ${formName} submission '${logId}' from the BAP.`; - return res.status(errorStatus).json({ message: errorMessage }); - } - - const { - UEI_EFTI_Combo_Key__c, - CSB_Form_ID__c, - CSB_Modified_Full_String__c, - CSB_Review_Item_ID__c, - Parent_Rebate_ID__c, - Record_Type_Name__c, - Parent_CSB_Rebate__r, - } = bapSubmission; - - return Promise.all([ - axiosFormio(req).get(`${formioFormUrl}/submission/${CSB_Form_ID__c}`), - axiosFormio(req).get(formioFormUrl), - ]) - .then((responses) => responses.map((axiosRes) => axiosRes.data)) - .then(([formioSubmission, schema]) => { - return res.json({ - formSchema: { url: formioFormUrl, json: schema }, - formio: formioSubmission, - bap: { - modified: CSB_Modified_Full_String__c, // ISO 8601 date time string - comboKey: UEI_EFTI_Combo_Key__c, // UEI + EFTI combo key - mongoId: CSB_Form_ID__c, // MongoDB Object ID - rebateId: Parent_Rebate_ID__c, // CSB Rebate ID (6 digits) - reviewItemId: CSB_Review_Item_ID__c, // CSB Rebate ID with form/version ID (9 digits) - status: - Record_Type_Name__c === "CSB Funding Request" - ? Parent_CSB_Rebate__r?.CSB_Funding_Request_Status__c - : Record_Type_Name__c === "CSB Payment Request" - ? Parent_CSB_Rebate__r?.CSB_Payment_Request_Status__c - : Record_Type_Name__c === "CSB Close Out Request" - ? Parent_CSB_Rebate__r?.CSB_Closeout_Request_Status__c - : "", - }, - }); - }) - .catch((error) => { - // NOTE: error is logged in axiosFormio response interceptor - const errorStatus = error.response?.status || 500; - const errorMessage = `Error getting ${rebateYear} ${formName} submission '${CSB_Form_ID__c}'.`; - return res.status(errorStatus).json({ message: errorMessage }); - }); - }, - ); + }); }); module.exports = router; diff --git a/app/server/app/utilities/bap.js b/app/server/app/utilities/bap.js index b9db7a86..a2654d19 100644 --- a/app/server/app/utilities/bap.js +++ b/app/server/app/utilities/bap.js @@ -44,7 +44,13 @@ const { submissionPeriodOpen } = require("../config/formio"); * @property {string} CSB_Modified_Full_String__c * @property {string} CSB_Review_Item_ID__c * @property {string} Parent_Rebate_ID__c - * @property {string} Record_Type_Name__c + * @property {'CSB Funding Request' + * | 'CSB Payment Request' + * | 'CSB Close Out Request' + * | 'CSB Funding Request 2023' + * | 'CSB Payment Request 2023' + * | 'CSB Close Out Request 2023' + * } Record_Type_Name__c * @property {string | null} Rebate_Program_Year__c * @property {{ * CSB_Funding_Request_Status__c: string @@ -389,12 +395,19 @@ async function queryForSamEntities(req, email) { * statuses and related metadata. * * @param {express.Request} req + * @param {'2022' | '2023'} rebateYear * @param {'frf' | 'prf' | 'crf'} formType * @param {string | null} rebateId * @param {string | null} mongoId * @returns {Promise} fields associated a form submission */ -async function queryForBapFormSubmissionData(req, formType, rebateId, mongoId) { +async function queryForBapFormSubmissionData( + req, + rebateYear, + formType, + rebateId, + mongoId, +) { const logId = rebateId ? `rebateId: '${rebateId}'` : `mongoId: '${mongoId}'`; const logMessage = `Querying the BAP for ${formType.toUpperCase()} submission data ` + @@ -404,14 +417,20 @@ async function queryForBapFormSubmissionData(req, formType, rebateId, mongoId) { /** @type {jsforce.Connection} */ const { bapConnection } = req.app.locals; - const developerName = - formType === "frf" - ? "CSB_Funding_Request" - : formType === "prf" - ? "CSB_Payment_Request" - : formType === "crf" - ? "CSB_Closeout_Request" - : null; // fallback + const developerNameField = { + 2022: { + frf: "CSB_Funding_Request", + prf: "CSB_Payment_Request", + crf: "CSB_Closeout_Request", + }, + 2023: { + frf: "CSB_Funding_Request_2023", + prf: null, // "CSB_Payment_Request_2023" + crf: null, // "CSB_Closeout_Request_2023" + }, + }; + + const developerName = developerNameField[rebateYear][formType]; if (!developerName) return null; @@ -448,6 +467,7 @@ async function queryForBapFormSubmissionData(req, formType, rebateId, mongoId) { // CSB_Review_Item_ID__c, // Parent_Rebate_ID__c, // Record_Type_Name__c, + // Rebate_Program_Year__c, // Parent_CSB_Rebate__r.CSB_Funding_Request_Status__c, // Parent_CSB_Rebate__r.CSB_Payment_Request_Status__c, // Parent_CSB_Rebate__r.CSB_Closeout_Request_Status__c @@ -474,7 +494,8 @@ async function queryForBapFormSubmissionData(req, formType, rebateId, mongoId) { CSB_Modified_Full_String__c: 1, // ISO 8601 date time string CSB_Review_Item_ID__c: 1, // CSB Rebate ID with form/version ID (9 digits) Parent_Rebate_ID__c: 1, // CSB Rebate ID (6 digits) - Record_Type_Name__c: 1, // 'CSB Funding Request' | 'CSB Payment Request' | 'CSB Close Out Request' + Record_Type_Name__c: 1, // 'CSB Funding Request' | 'CSB Payment Request' | 'CSB Close Out Request' | 'CSB Funding Request 2023' | 'CSB Payment Request 2023' | 'CSB Close Out Request 2023' + Rebate_Program_Year__c: 1, // '2022' | '2023' "Parent_CSB_Rebate__r.CSB_Funding_Request_Status__c": 1, "Parent_CSB_Rebate__r.CSB_Payment_Request_Status__c": 1, "Parent_CSB_Rebate__r.CSB_Closeout_Request_Status__c": 1, @@ -1348,16 +1369,24 @@ function getBapComboKeys(req, email) { /** * Fetches data associated with a provided form submission. * - * @param {express.Request} req - * @param {'frf' | 'prf' | 'crf'} formType - * @param {string | null} rebateId - * @param {string | null} mongoId + * @param {Object} param + * @param {'2022' | '2023'} param.rebateYear + * @param {'frf' | 'prf' | 'crf'} param.formType + * @param {string | null} param.rebateId + * @param {string | null} param.mongoId + * @param {express.Request} param.req * @returns {ReturnType} */ -function getBapFormSubmissionData(req, formType, rebateId, mongoId) { +function getBapFormSubmissionData({ + rebateYear, + formType, + rebateId, + mongoId, + req, +}) { return verifyBapConnection(req, { name: queryForBapFormSubmissionData, - args: [req, formType, rebateId, mongoId], + args: [req, rebateYear, formType, rebateId, mongoId], }); }