Hi,
I think this behavior should be done in Power Automate or a plugin.
However, I have modified your javascript code, and I have some questions.
async function getContacts(executionContext) {
const formContext = executionContext.getFormContext();
const accountLookup = formContext.getAttribute("e3_client").getValue();
if (!accountLookup) {
return; // No account lookup value, so exit the function
}
try {
// Get the account GUID
const accountId = accountLookup[0].id;
// Retrieve Vendor Agreement and BAA
const vaPromise = Xrm.WebApi.retrieveMultipleRecords("e3_vendoragreement", `?$select=_e3_vendor_value&$filter=_e3_client_value eq ${accountId}`);
const baaPromise = Xrm.WebApi.retrieveMultipleRecords("e3_businessassociateagreement", `?$select=_e3_vendor_value&$filter=_e3_client_value eq ${accountId}`);
const [vaRecords, baaRecords] = await Promise.all([vaPromise, baaPromise]); // Wait for both promises to resolve. Improves performance.
const uniqueVendorIds = [...new Set( // Remove duplicates. See https://stackoverflow.com/a/14438954/2001966
[...vaRecords.entities, ...baaRecords.entities] // Combine the two arrays with the spread operator
.map(entity => entity._e3_vendor_value) // Get the vendor lookup value
)];
if (uniqueVendorIds.length === 0) {
throw new Error("No vendor agreements or business associate agreements found.");
}
// IMPORTANT: I am not sure about this query, can you tell more about the relationship between the entities?
const contactQuery = `?$select=fullname&$filter=(e3_account/e3_account_contact_account/any(o:o/e3_account eq ${accountId}))`
`or (e3_vendoraccount/e3_e3_vendor_contact_vendoraccount/any(o:o/e3_vendoraccount eq ${uniqueVendorIds.join(" or e3_vendor eq ")}))`;
// Retrieve Contact records
const contactsResult = await Xrm.WebApi.retrieveMultipleRecords("contact", contactQuery);
if (contactsResult.entities.length === 0) {
throw new Error("No contacts found.");
}
if (contactsResult.entities.length > 1) {
formContext.ui.setFormNotification(`Found ${contactLookupValues.length} contacts. Only the first one will be set as primary.`, "WARNING", "1");
}
// Create an array of lookup values
const contactLookupValues = contactsResult.entities
.map(entity => ({
id: entity.contactid,
name: entity.fullname,
entityType: "contact"
}));
formContext.getAttribute("primarycontactid").setValue([contactLookupValues[0]]); // Only one contact can be set as primary
}
catch (error) {
Xrm.Navigation.openAlertDialog({ text: `An error was occurred: ${error.message}. Stacktrace: ${error.stack}` });
}
}
I used modern javascript code: const, promises with async/await, set, map, string interpolation, spread operator, arrow function...
I fixed a problem with the lookup assignment. The primarycontactid lookup can only take one contact and it must be assigned as an object with id, name, entityType properties. What should you do if there are multiple contacts?
However, I think your problem is located in the contactQuery. Can you tell me more about the relationship between the entities?