From 416e1f45706d52948f80c4f24e3d39c3957da619 Mon Sep 17 00:00:00 2001 From: Courtney Myers Date: Tue, 26 Mar 2024 09:53:06 -0400 Subject: [PATCH 1/7] Split school district address field on new line character returned from BAP query for address lines 1 and 2 --- app/server/app/utilities/formio.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/server/app/utilities/formio.js b/app/server/app/utilities/formio.js index 19720437..069dcf8a 100644 --- a/app/server/app/utilities/formio.js +++ b/app/server/app/utilities/formio.js @@ -191,6 +191,10 @@ function fetchDataForPRFSubmission({ rebateYear, req, res }) { Prioritized_as_Rural__c, } = frf2023RecordQuery[0]; + const [schoolDistrictAddress1, schoolDistrictAddress2] = ( + CSB_School_District__r?.BillingStreet ?? "\n" + ).split("\n"); + // TODO: ask BAP for the query for the fields below. // NOTE: the data from the 2023 FRF is in an 'organizations' field (array of objects) // which has the exact same fields below, except for "_org_typeCombined" @@ -330,8 +334,8 @@ function fetchDataForPRFSubmission({ rebateYear, req, res }) { _bap_alternate_phone_number: Alternate_Applicant__r?.Phone, _bap_district_ncesID: CSB_NCES_ID__c, _bap_district_name: CSB_School_District__r?.Name, - _bap_district_address_1: CSB_School_District__r?.BillingStreet, // TODO: once BAP returns this field with a new line character, split on it for address line 1 and 2 - _bap_district_address_2: "", // TODO: see above + _bap_district_address_1: schoolDistrictAddress1 || "", + _bap_district_address_2: schoolDistrictAddress2 || "", _bap_district_city: CSB_School_District__r?.BillingCity, _bap_district_state: CSB_School_District__r?.BillingState, _bap_district_zip: CSB_School_District__r?.BillingPostalCode, From 51dd6245577b9d88dfd3da480b887edf7f0fb6b4 Mon Sep 17 00:00:00 2001 From: Courtney Myers Date: Tue, 26 Mar 2024 15:49:27 -0400 Subject: [PATCH 2/7] Update getBapDataFor2023PRF() to set existing bus owner via the bus records contact with the Relationship_Type__c field with 'Old Bus Private Fleet Owner (if changed)' value --- app/server/app/utilities/formio.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/server/app/utilities/formio.js b/app/server/app/utilities/formio.js index 069dcf8a..ecf8421b 100644 --- a/app/server/app/utilities/formio.js +++ b/app/server/app/utilities/formio.js @@ -250,7 +250,8 @@ function fetchDataForPRFSubmission({ rebateYear, req, res }) { ({ Related_Line_Item__c, Relationship_Type__c }) => { return ( Related_Line_Item__c === Id && - Relationship_Type__c === "Existing Bus Owner" + Relationship_Type__c === + "Old Bus Private Fleet Owner (if changed)" ); }, ); From d7f65b56eb7843fc6dd995e6e493fa6d334a14f1 Mon Sep 17 00:00:00 2001 From: Courtney Myers Date: Tue, 26 Mar 2024 16:21:50 -0400 Subject: [PATCH 3/7] Update frf2023BusRecordsContactsQueries to include additional contact fields (Id, Title, Email, Phone, and AccountId) --- app/server/app/utilities/bap.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/server/app/utilities/bap.js b/app/server/app/utilities/bap.js index 7eac42c7..57934eb6 100644 --- a/app/server/app/utilities/bap.js +++ b/app/server/app/utilities/bap.js @@ -172,8 +172,13 @@ const { submissionPeriodOpen } = require("../config/formio"); * Relationship_Type__c: string * Contact_Organization_Name__c: string * Contact__r: { + * Id: string * FirstName: string * LastName: string + * Title: string + * Email: string + * Phone: string + * AccountId: string * } | null * }[]} frf2023BusRecordsContactsQueries * @property {{ @@ -982,8 +987,13 @@ async function queryBapFor2023PRFData(req, frfReviewItemId) { // Related_Line_Item__c, // Relationship_Type__c, // Contact_Organization_Name__c, + // Contact__r.Id, // Contact__r.FirstName, // Contact__r.LastName + // Contact__r.Title, + // Contact__r.Email, + // Contact__r.Phone, + // Contact__r.AccountId // FROM // Line_Item__c // WHERE @@ -1005,8 +1015,13 @@ async function queryBapFor2023PRFData(req, frfReviewItemId) { Related_Line_Item__c: 1, Relationship_Type__c: 1, Contact_Organization_Name__c: 1, + "Contact__r.Id": 1, "Contact__r.FirstName": 1, "Contact__r.LastName": 1, + "Contact__r.Title": 1, + "Contact__r.Email": 1, + "Contact__r.Phone": 1, + "Contact__r.AccountId": 1, }, ) .execute(async (err, records) => ((await err) ? err : records)); From a45b1eb4922d15ce5831bd74852833399d2dbf60 Mon Sep 17 00:00:00 2001 From: Courtney Myers Date: Tue, 26 Mar 2024 16:26:57 -0400 Subject: [PATCH 4/7] Remove org field from bus_existingOnwer and bus_newOwner objects in new PRF data --- app/server/app/utilities/formio.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/server/app/utilities/formio.js b/app/server/app/utilities/formio.js index ecf8421b..98043565 100644 --- a/app/server/app/utilities/formio.js +++ b/app/server/app/utilities/formio.js @@ -268,7 +268,6 @@ function fetchDataForPRFSubmission({ rebateYear, req, res }) { return { bus_busNumber: Rebate_Item_num__c, bus_existingOwner: { - org: "", // TODO: ask BAP how to get this value organization: existingOwnerRecord?.Contact_Organization_Name__c, orgContactFName: existingOwnerRecord?.Contact__r?.FirstName, orgContactLName: existingOwnerRecord?.Contact__r?.LastName, @@ -287,7 +286,6 @@ function fetchDataForPRFSubmission({ rebateYear, req, res }) { bus_existingRemainingLife: Old_Bus_Estimated_Remaining_Life__c, bus_existingIdlingHours: Old_Bus_Annual_Idling_Hours__c, bus_newOwner: { - org: "", // TODO: ask BAP how to get this value organization: newOwnerRecord?.Contact_Organization_Name__c, orgContactFName: newOwnerRecord?.Contact__r?.FirstName, orgContactLName: newOwnerRecord?.Contact__r?.LastName, From 1dee04c33f835b9bfc9f2f6b34a7e801d3ec6529 Mon Sep 17 00:00:00 2001 From: Courtney Myers Date: Tue, 26 Mar 2024 17:10:16 -0400 Subject: [PATCH 5/7] Update frf2023BusRecordsContactsQueries array to be flattened when storing data --- app/server/app/utilities/bap.js | 102 ++++++++++++++++---------------- 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/app/server/app/utilities/bap.js b/app/server/app/utilities/bap.js index 57934eb6..10b704af 100644 --- a/app/server/app/utilities/bap.js +++ b/app/server/app/utilities/bap.js @@ -978,60 +978,62 @@ async function queryBapFor2023PRFData(req, frfReviewItemId) { ) .execute(async (err, records) => ((await err) ? err : records)); - const frf2023BusRecordsContactsQueries = await Promise.all( - frf2023BusRecordsQuery.map(async (frf2023BusRecord) => { - const frf2023BusRecordId = frf2023BusRecord.Id; - - // `SELECT - // Id, - // Related_Line_Item__c, - // Relationship_Type__c, - // Contact_Organization_Name__c, - // Contact__r.Id, - // Contact__r.FirstName, - // Contact__r.LastName - // Contact__r.Title, - // Contact__r.Email, - // Contact__r.Phone, - // Contact__r.AccountId - // FROM - // Line_Item__c - // WHERE - // RecordTypeId = '${rebateItemRecordTypeId}' AND - // Related_Line_Item__c = '${frf2023BusRecordId}' AND - // CSB_Rebate_Item_Type__c = 'COF Relationship'` - - return await bapConnection - .sobject("Line_Item__c") - .find( - { - RecordTypeId: rebateItemRecordTypeId, - Related_Line_Item__c: frf2023BusRecordId, - CSB_Rebate_Item_Type__c: "COF Relationship", - }, - { - // "*": 1, - Id: 1, // Salesforce record ID - Related_Line_Item__c: 1, - Relationship_Type__c: 1, - Contact_Organization_Name__c: 1, - "Contact__r.Id": 1, - "Contact__r.FirstName": 1, - "Contact__r.LastName": 1, - "Contact__r.Title": 1, - "Contact__r.Email": 1, - "Contact__r.Phone": 1, - "Contact__r.AccountId": 1, - }, - ) - .execute(async (err, records) => ((await err) ? err : records)); - }), - ); + const frf2023BusRecordsContactsQueries = ( + await Promise.all( + frf2023BusRecordsQuery.map(async (frf2023BusRecord) => { + const frf2023BusRecordId = frf2023BusRecord.Id; + + // `SELECT + // Id, + // Related_Line_Item__c, + // Relationship_Type__c, + // Contact_Organization_Name__c, + // Contact__r.Id, + // Contact__r.FirstName, + // Contact__r.LastName + // Contact__r.Title, + // Contact__r.Email, + // Contact__r.Phone, + // Contact__r.AccountId + // FROM + // Line_Item__c + // WHERE + // RecordTypeId = '${rebateItemRecordTypeId}' AND + // Related_Line_Item__c = '${frf2023BusRecordId}' AND + // CSB_Rebate_Item_Type__c = 'COF Relationship'` + + return await bapConnection + .sobject("Line_Item__c") + .find( + { + RecordTypeId: rebateItemRecordTypeId, + Related_Line_Item__c: frf2023BusRecordId, + CSB_Rebate_Item_Type__c: "COF Relationship", + }, + { + // "*": 1, + Id: 1, // Salesforce record ID + Related_Line_Item__c: 1, + Relationship_Type__c: 1, + Contact_Organization_Name__c: 1, + "Contact__r.Id": 1, + "Contact__r.FirstName": 1, + "Contact__r.LastName": 1, + "Contact__r.Title": 1, + "Contact__r.Email": 1, + "Contact__r.Phone": 1, + "Contact__r.AccountId": 1, + }, + ) + .execute(async (err, records) => ((await err) ? err : records)); + }), + ) + ).flat(); return { frf2023RecordQuery, frf2023BusRecordsQuery, - frf2023BusRecordsContactsQueries: frf2023BusRecordsContactsQueries.flat(), + frf2023BusRecordsContactsQueries, }; } From 7e4869190ca7e2dafd740a47913ec2ca90545e22 Mon Sep 17 00:00:00 2001 From: Courtney Myers Date: Tue, 26 Mar 2024 21:56:30 -0400 Subject: [PATCH 6/7] Update queryBapFor2023PRFData() to query the bus records contacts accounts data too (for the org address info, since it's not included on the bus records contacts themselves) --- app/server/app/utilities/bap.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/app/server/app/utilities/bap.js b/app/server/app/utilities/bap.js index 10b704af..821c8dca 100644 --- a/app/server/app/utilities/bap.js +++ b/app/server/app/utilities/bap.js @@ -182,6 +182,15 @@ const { submissionPeriodOpen } = require("../config/formio"); * } | null * }[]} frf2023BusRecordsContactsQueries * @property {{ + * Id: string + * Name: string + * BillingStreet: string + * BillingCountry: string + * BillingCity: string + * BillingState: string + * BillingPostalCode: string + * }[]} frf2023BusRecordsContactsOrgsQueries + * @property {{ * type: string * url: string * }} attributes @@ -1030,10 +1039,23 @@ async function queryBapFor2023PRFData(req, frfReviewItemId) { ) ).flat(); + const frf2023BusRecordsContactsAccountIds = [ + ...new Set( + frf2023BusRecordsContactsQueries.map((item) => item.Contact__r.AccountId), + ), + ]; + + const frf2023BusRecordsContactsOrgsQueries = await bapConnection + .sobject("Account") + .retrieve(frf2023BusRecordsContactsAccountIds, async (err, records) => + (await err) ? err : records, + ); + return { frf2023RecordQuery, frf2023BusRecordsQuery, frf2023BusRecordsContactsQueries, + frf2023BusRecordsContactsOrgsQueries, }; } From 4b741a901645a8bc039d8b6084c72beb97f5fa94 Mon Sep 17 00:00:00 2001 From: Courtney Myers Date: Tue, 26 Mar 2024 21:58:33 -0400 Subject: [PATCH 7/7] Update getBapDataFor2023PRF() to use bus records contacts org queries result to build up organizations array, and include it in the returned JSON data for a brand new 2023 PRF --- app/server/app/utilities/formio.js | 111 ++++++++++++++++++----------- 1 file changed, 69 insertions(+), 42 deletions(-) diff --git a/app/server/app/utilities/formio.js b/app/server/app/utilities/formio.js index 98043565..5b8103ad 100644 --- a/app/server/app/utilities/formio.js +++ b/app/server/app/utilities/formio.js @@ -176,8 +176,12 @@ function fetchDataForPRFSubmission({ rebateYear, req, res }) { frf2023RecordQuery, frf2023BusRecordsQuery, frf2023BusRecordsContactsQueries, + frf2023BusRecordsContactsOrgsQueries, } = results; + const existingBusOwnerType = "Old Bus Private Fleet Owner (if changed)"; + const newBusOwnerType = "New Bus Owner"; + const { Primary_Applicant__r, Alternate_Applicant__r, @@ -191,37 +195,67 @@ function fetchDataForPRFSubmission({ rebateYear, req, res }) { Prioritized_as_Rural__c, } = frf2023RecordQuery[0]; - const [schoolDistrictAddress1, schoolDistrictAddress2] = ( + const [schoolDistrictStreetAddress1, schoolDistrictStreetAddress2] = ( CSB_School_District__r?.BillingStreet ?? "\n" ).split("\n"); - // TODO: ask BAP for the query for the fields below. - // NOTE: the data from the 2023 FRF is in an 'organizations' field (array of objects) - // which has the exact same fields below, except for "_org_typeCombined" - const org_organizations = new Array(0).map((item) => ({ - org_number: Infinity, - org_type: { - existingBusOwner: true, - newBusOwner: true, - privateFleet: false, - }, - _org_typeCombined: "", // NOTE: was 'org_hidden_type' in the FRF (example value: 'Existing Bus Owner, New Bus Owner') - org_orgName: "", - org_contactFName: "", - org_contactLName: "", - org_contactTitle: "", - org_contactEmail: "", - org_contactPhone: "", - org_address1: "", - org_address2: "", - org_county: "", - org_city: "", - org_state: { - name: "", - abbreviation: "", + const org_organizations = frf2023BusRecordsContactsOrgsQueries.map( + (frf2023BusRecordsContactsOrgs) => { + const { + Id, + Name, + BillingStreet, + BillingCountry, + BillingCity, + BillingState, + BillingPostalCode, + } = frf2023BusRecordsContactsOrgs; + + const [orgStreetAddress1, orgStreetAddress2] = ( + BillingStreet ?? "\n" + ).split("\n"); + + const orgContacts = frf2023BusRecordsContactsQueries.filter( + (item) => item.Contact__r.AccountId === Id, + ); + + const existingBusOwner = orgContacts.some( + (item) => item.Relationship_Type__c === existingBusOwnerType, + ); + + const newBusOwner = orgContacts.some( + (item) => item.Relationship_Type__c === newBusOwnerType, + ); + + const { FirstName, LastName, Title, Email, Phone } = + orgContacts[0].Contact__r ?? {}; + + return { + org_number: null, + org_type: { + existingBusOwner, + newBusOwner, + // privateFleet: false, + }, + // _org_typeCombined: "", // NOTE: 'Existing Bus Owner, New Bus Owner' + org_orgName: Name, + org_contactFName: FirstName, + org_contactLName: LastName, + org_contactTitle: Title, + org_contactEmail: Email, + org_contactPhone: Phone, + org_address1: orgStreetAddress1, + org_address2: orgStreetAddress2, + org_county: BillingCountry, + org_city: BillingCity, + org_state: { + name: BillingState, + // abbreviation: "", + }, + org_zip: BillingPostalCode, + }; }, - org_zip: "", - })); + ); const bus_buses = frf2023BusRecordsQuery.map((frf2023BusRecord) => { const { @@ -247,22 +281,15 @@ function fetchDataForPRFSubmission({ rebateYear, req, res }) { } = frf2023BusRecord; const existingOwnerRecord = frf2023BusRecordsContactsQueries.find( - ({ Related_Line_Item__c, Relationship_Type__c }) => { - return ( - Related_Line_Item__c === Id && - Relationship_Type__c === - "Old Bus Private Fleet Owner (if changed)" - ); - }, + (item) => + item.Related_Line_Item__c === Id && + item.Relationship_Type__c === existingBusOwnerType, ); const newOwnerRecord = frf2023BusRecordsContactsQueries.find( - ({ Related_Line_Item__c, Relationship_Type__c }) => { - return ( - Related_Line_Item__c === Id && - Relationship_Type__c === "New Bus Owner" - ); - }, + (item) => + item.Related_Line_Item__c === Id && + item.Relationship_Type__c === newBusOwnerType, ); return { @@ -333,8 +360,8 @@ function fetchDataForPRFSubmission({ rebateYear, req, res }) { _bap_alternate_phone_number: Alternate_Applicant__r?.Phone, _bap_district_ncesID: CSB_NCES_ID__c, _bap_district_name: CSB_School_District__r?.Name, - _bap_district_address_1: schoolDistrictAddress1 || "", - _bap_district_address_2: schoolDistrictAddress2 || "", + _bap_district_address_1: schoolDistrictStreetAddress1 || "", + _bap_district_address_2: schoolDistrictStreetAddress2 || "", _bap_district_city: CSB_School_District__r?.BillingCity, _bap_district_state: CSB_School_District__r?.BillingState, _bap_district_zip: CSB_School_District__r?.BillingPostalCode,