feat: Salesforce when create contacts under an account if creating leads is chosen [CAL-4713] (#17630)
This commit is contained in:
1 parent
ff2754f663
commit
3589767099
2 files changed
+134
-52
No files matched your search
@@ -93,6 +93,20 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
|
||||
value: "",
|
||||
});
|
||||
|
||||
// Used when creating events under leads or contacts under account
|
||||
const CreateContactUnderAccount = () => {
|
||||
return (
|
||||
<Switch
|
||||
label={t("salesforce_create_new_contact_under_account")}
|
||||
labelOnLeading
|
||||
checked={createNewContactUnderAccount}
|
||||
onCheckedChange={(checked) => {
|
||||
setAppData("createNewContactUnderAccount", checked);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<AppCard
|
||||
returnTo={`${WEBAPP_URL}${pathname}?tabName=apps`}
|
||||
@@ -142,19 +156,15 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
|
||||
setAppData("createEventOnLeadCheckForContact", checked);
|
||||
}}
|
||||
/>
|
||||
<div className="mt-4">
|
||||
<CreateContactUnderAccount />
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
{createEventOnSelectedOption.value === SalesforceRecordEnum.ACCOUNT ? (
|
||||
<>
|
||||
<div className="mb-4">
|
||||
<Switch
|
||||
label={t("salesforce_create_new_contact_under_account")}
|
||||
labelOnLeading
|
||||
checked={createNewContactUnderAccount}
|
||||
onCheckedChange={(checked) => {
|
||||
setAppData("createNewContactUnderAccount", checked);
|
||||
}}
|
||||
/>
|
||||
<CreateContactUnderAccount />
|
||||
</div>
|
||||
<div>
|
||||
<Switch
|
||||
|
||||
@@ -42,6 +42,8 @@ type ContactRecord = {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
type Attendee = { email: string; name: string };
|
||||
|
||||
const salesforceTokenSchema = z.object({
|
||||
id: z.string(),
|
||||
issued_at: z.string(),
|
||||
@@ -398,35 +400,56 @@ export default class SalesforceCRMService implements CRM {
|
||||
: [];
|
||||
}
|
||||
|
||||
async createContacts(contactsToCreate: { email: string; name: string }[], organizerEmail?: string) {
|
||||
async createContacts(contactsToCreate: Attendee[], organizerEmail?: string) {
|
||||
const conn = await this.conn;
|
||||
const appOptions = this.getAppOptions();
|
||||
const createEventOn = appOptions.createEventOn ?? SalesforceRecordEnum.CONTACT;
|
||||
// See if the organizer exists in the CRM
|
||||
const organizerId = organizerEmail ? await this.getSalesforceUserIdFromEmail(organizerEmail) : undefined;
|
||||
const createdContacts: { id: string; email: string }[] = [];
|
||||
|
||||
if (createEventOn === SalesforceRecordEnum.CONTACT || createEventOn === SalesforceRecordEnum.LEAD) {
|
||||
// See if the organizer exists in the CRM
|
||||
if (createEventOn === SalesforceRecordEnum.CONTACT) {
|
||||
await Promise.all(
|
||||
contactsToCreate.map(async (attendee) => {
|
||||
return await conn
|
||||
.sobject(createEventOn)
|
||||
.create(
|
||||
this.generateCreateRecordBody({
|
||||
attendee,
|
||||
recordType: createEventOn,
|
||||
organizerId,
|
||||
})
|
||||
)
|
||||
.then((result) => {
|
||||
if (result.success) {
|
||||
createdContacts.push({ id: result.id, email: attendee.email });
|
||||
}
|
||||
});
|
||||
return await this.createAttendeeRecord({
|
||||
attendee,
|
||||
recordType: SalesforceRecordEnum.CONTACT,
|
||||
organizerId,
|
||||
}).then((result) => {
|
||||
createdContacts.push(...result);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (createEventOn === SalesforceRecordEnum.LEAD) {
|
||||
// Base this off of the first contact
|
||||
const attendee = contactsToCreate[0];
|
||||
|
||||
if (appOptions.createNewContactUnderAccount) {
|
||||
// Check for an account
|
||||
const accountId = await this.getAccountIdBasedOnEmailDomainOfContacts(attendee.email);
|
||||
|
||||
if (accountId) {
|
||||
const createdAccountContacts = await this.createNewContactUnderAnAccount({
|
||||
attendee,
|
||||
accountId,
|
||||
organizerId,
|
||||
});
|
||||
|
||||
if (createdContacts.length > 0) {
|
||||
createdContacts.push(...createdAccountContacts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await this.createAttendeeRecord({ attendee, recordType: SalesforceRecordEnum.LEAD, organizerId }).then(
|
||||
(result) => {
|
||||
createdContacts.push(...result);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (createEventOn === SalesforceRecordEnum.ACCOUNT) {
|
||||
if (!appOptions.createNewContactUnderAccount && !appOptions.createLeadIfAccountNull) {
|
||||
this.setDoNotCreateEvent(true);
|
||||
@@ -441,34 +464,16 @@ export default class SalesforceCRMService implements CRM {
|
||||
let contactCreated = false;
|
||||
|
||||
if (accountId && appOptions.createNewContactUnderAccount) {
|
||||
// First see if the contact already exists and connect it to the account
|
||||
const userQuery = await conn.query(`SELECT Id, Email FROM Contact WHERE Email = '${attendee.email}'`);
|
||||
if (userQuery.records.length) {
|
||||
const contact = userQuery.records[0] as { Id: string; Email: string };
|
||||
await conn.sobject(SalesforceRecordEnum.CONTACT).update({
|
||||
// The first argument is the WHERE clause
|
||||
Id: contact.Id,
|
||||
AccountId: accountId,
|
||||
});
|
||||
return [{ id: contact.Id, email: contact.Email }];
|
||||
}
|
||||
const createdAccountContacts = await this.createNewContactUnderAnAccount({
|
||||
attendee,
|
||||
accountId,
|
||||
organizerId,
|
||||
});
|
||||
|
||||
await conn
|
||||
.sobject(SalesforceRecordEnum.CONTACT)
|
||||
.create({
|
||||
...this.generateCreateRecordBody({
|
||||
attendee,
|
||||
recordType: SalesforceRecordEnum.CONTACT,
|
||||
organizerId,
|
||||
}),
|
||||
AccountId: accountId,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.success) {
|
||||
createdContacts.push({ id: result.id, email: attendee.email });
|
||||
contactCreated = true;
|
||||
}
|
||||
});
|
||||
if (createdContacts.length > 0) {
|
||||
createdContacts.push(...createdAccountContacts);
|
||||
contactCreated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!accountId && appOptions.createLeadIfAccountNull && !contactCreated) {
|
||||
@@ -629,6 +634,42 @@ export default class SalesforceCRMService implements CRM {
|
||||
return dominantAccountId;
|
||||
}
|
||||
|
||||
private async createAttendeeRecord({
|
||||
attendee,
|
||||
recordType,
|
||||
organizerId,
|
||||
accountId,
|
||||
}: {
|
||||
attendee: Attendee;
|
||||
recordType: SalesforceRecordEnum;
|
||||
organizerId?: string;
|
||||
accountId?: string;
|
||||
}) {
|
||||
const conn = await this.conn;
|
||||
|
||||
return await conn
|
||||
.sobject(recordType)
|
||||
.create({
|
||||
...this.generateCreateRecordBody({
|
||||
attendee,
|
||||
recordType: recordType,
|
||||
organizerId,
|
||||
}),
|
||||
AccountId: accountId,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.success) {
|
||||
return [{ id: result.id, email: attendee.email }];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.log.error(`Error creating Salesforce contact for ${attendee.email} with error ${error}`);
|
||||
return [];
|
||||
});
|
||||
}
|
||||
|
||||
private generateCreateRecordBody({
|
||||
attendee,
|
||||
recordType,
|
||||
@@ -864,6 +905,37 @@ export default class SalesforceCRMService implements CRM {
|
||||
return query.records[0] as Record<string, any>;
|
||||
}
|
||||
|
||||
private async createNewContactUnderAnAccount({
|
||||
attendee,
|
||||
accountId,
|
||||
organizerId,
|
||||
}: {
|
||||
attendee: Attendee;
|
||||
accountId: string;
|
||||
organizerId?: string;
|
||||
}) {
|
||||
const conn = await this.conn;
|
||||
|
||||
// First see if the contact already exists and connect it to the account
|
||||
const userQuery = await conn.query(`SELECT Id, Email FROM Contact WHERE Email = '${attendee.email}'`);
|
||||
if (userQuery.records.length) {
|
||||
const contact = userQuery.records[0] as { Id: string; Email: string };
|
||||
await conn.sobject(SalesforceRecordEnum.CONTACT).update({
|
||||
// The first argument is the WHERE clause
|
||||
Id: contact.Id,
|
||||
AccountId: accountId,
|
||||
});
|
||||
return [{ id: contact.Id, email: contact.Email }];
|
||||
}
|
||||
|
||||
return await this.createAttendeeRecord({
|
||||
attendee,
|
||||
recordType: SalesforceRecordEnum.CONTACT,
|
||||
accountId,
|
||||
organizerId,
|
||||
});
|
||||
}
|
||||
|
||||
async findUserEmailFromLookupField(
|
||||
attendeeEmail: string,
|
||||
fieldName: string,
|
||||
|
||||
Reference in new issue
Block a user