Skip to content

Commit 711ada8

Browse files
authored
[CRM] Add the possibility to log your own mail to an opportunity
When outlook is displaying one of your own answers, the extension - shows your client's details instead of your own - allows logging the content of your own answer to the opportunitie of the client Additionally: In EnrichmentInfo, the constructor would override the `info` returned by the service with its own message. Then the Main would use that message as the url to buy more credits. Now the `info` field is not overridden anymore, and the Main uses the `EnrichmentInfo.getTypicalMessage` function to get the message. Task ID: 2376540
1 parent dbc2323 commit 711ada8

File tree

5 files changed

+49
-15
lines changed

5 files changed

+49
-15
lines changed

outlook/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,20 @@
66
- `npm install`
77
- `npm run-script build -- --env.DOMAIN=127.0.0.1:8080` (replace `127.0.0.1:8080` with the actual domain)
88
- serve the dist folder
9+
10+
## To add the add-in in outlook for the web
11+
12+
- Open any email
13+
- Click the three dot in the upper right corner of the mail
14+
- Click "Get add-ins"
15+
- Select "My add-ins"
16+
- Click the link "Add a custom add-in"
17+
- Select "Add from URL"
18+
- Paste the URL to the manifest.xml. E.g. https://download.odoo.com/plugins/outlook/manifest.xml
19+
20+
## To pin the add-in
21+
22+
- Click the cog in the upper right corner of the pain window
23+
- Select "View all Outlook settings"
24+
- Click "Mail" > "Customize actions"
25+
- Under the section "Message surface", check "Odoo for Outlook".

outlook/manifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
22
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:mailappor="http://schemas.microsoft.com/office/mailappversionoverrides/1.0" xsi:type="MailApp">
33
<Id>c5549a21-aefb-4ba8-ae7c-b77bceab4023</Id>
4-
<Version>1.0.2</Version>
4+
<Version>1.1.1</Version>
55
<ProviderName>Odoo</ProviderName>
66
<DefaultLocale>en-US</DefaultLocale>
77
<DisplayName DefaultValue="Odoo for Outlook"/>

outlook/src/classes/EnrichmentInfo.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@ class EnrichmentInfo {
1515

1616
constructor(type?:EnrichmentInfoType, info?:string) {
1717
this.type = type || EnrichmentInfoType.None;
18-
// Override the info returned by the service, unless we don't actually have a typical message.
19-
// Messages' content should come from only one place, and ideally the front end.
20-
this.info = this.getTypicalMessage(this.type) || info;
18+
this.info = info;
2119
}
2220

23-
public getTypicalMessage(type: EnrichmentInfoType) {
24-
switch (type) {
21+
getTypicalMessage = () => {
22+
switch (this.type) {
2523
case EnrichmentInfoType.None:
2624
return "";
2725
case EnrichmentInfoType.CompanyCreated:

outlook/src/taskpane/components/Leads/Leads.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ class Leads extends React.Component<LeadsProps, LeadsState> {
5757
Office.context.mailbox.item.body.getAsync(Office.CoercionType.Html, (result) => {
5858
const msgHeader = '<div>From: '+ Office.context.mailbox.item.sender.emailAddress + '</div><br/>';
5959
const msgFooter = '<br/><div class="text-muted font-italic">Logged from <a href="https://www.odoo.com/documentation/user/crm/optimize/mail_client_extension.html" target="_blank">Outlook Inbox</a></div>';
60-
const message = msgHeader + result.value + msgFooter;
60+
const body = result.value.split('<div id="x_appendonsend"></div>')[0]; // Remove the history and only log the most recent message.
61+
const message = msgHeader + body + msgFooter;
6162
const requestJson = {
6263
lead: leadId,
6364
message: message

outlook/src/taskpane/components/Main/Main.tsx

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,21 @@ class Main extends React.Component<MainProps, MainState> {
5353
this.loadOrReload();
5454
}
5555

56+
5657
_connectedFlow = () => {
5758
if (!Office.context.mailbox.item) {
5859
return;
5960
}
60-
61-
const email = Office.context.mailbox.item.from.emailAddress;
62-
const displayName = Office.context.mailbox.item.from.displayName;
61+
62+
// If outlook is showing the oultook user's answer, we pick the sender of the original email.
63+
// Which is most likely the first "to" address, until proven otherwise.
64+
let email = Office.context.mailbox.item.from.emailAddress;
65+
let displayName = Office.context.mailbox.item.from.displayName;
66+
if (Office.context.mailbox.userProfile.emailAddress == Office.context.mailbox.item.from.emailAddress) {
67+
email = Office.context.mailbox.item.to[0].emailAddress;
68+
displayName = Office.context.mailbox.item.to[0].displayName;
69+
}
70+
6371
this.context.setIsLoading(true);
6472

6573
const cancellablePartnerRequest = sendHttpRequest(HttpVerb.POST, api.baseURL + api.getPartner, ContentType.Json, this.context.getConnectionToken(), {
@@ -110,8 +118,16 @@ class Main extends React.Component<MainProps, MainState> {
110118
_disconnectedFlow() {
111119
Office.context.mailbox.getUserIdentityTokenAsync(idTokenResult=>{
112120
const userEmail = Office.context.mailbox.userProfile.emailAddress;
113-
const senderEmail = Office.context.mailbox.item.from.emailAddress;
114-
const senderDisplayName = Office.context.mailbox.item.from.displayName;
121+
122+
// The "sender" is the sender of the original mail.
123+
// If outlook is showing the oultook user's answer, we pick the sender of the original email.
124+
// Which is most likely the first "to" address, until proven otherwise.
125+
let senderEmail = Office.context.mailbox.item.from.emailAddress;
126+
let senderDisplayName = Office.context.mailbox.item.from.displayName;
127+
if (Office.context.mailbox.userProfile.emailAddress == Office.context.mailbox.item.from.emailAddress) {
128+
senderEmail = Office.context.mailbox.item.to[0].emailAddress;
129+
senderDisplayName = Office.context.mailbox.item.to[0].displayName;
130+
}
115131
const senderDomain = senderEmail.split('@')[1];
116132

117133
const partner = new PartnerData();
@@ -185,6 +201,7 @@ class Main extends React.Component<MainProps, MainState> {
185201

186202
_getMessageBars = () => {
187203
const {type, info} = this.state.EnrichmentInfo;
204+
const message = this.state.EnrichmentInfo.getTypicalMessage();
188205
let bars = [];
189206
if (this.state.showPartnerCreatedMessage && this.state.partnerCreated) {
190207
bars.push(<MessageBar messageBarType={MessageBarType.success} onDismiss={this._hidePartnerCreatedMessage}>Contact created</MessageBar>);
@@ -198,11 +215,12 @@ class Main extends React.Component<MainProps, MainState> {
198215
break;
199216
case EnrichmentInfoType.NoData:
200217
case EnrichmentInfoType.NotConnected_NoData:
201-
bars.push(<MessageBar messageBarType={MessageBarType.info} onDismiss={this._hideEnrichmentInfoMessage}>{info}</MessageBar>);
218+
bars.push(<MessageBar messageBarType={MessageBarType.info} onDismiss={this._hideEnrichmentInfoMessage}>{message}</MessageBar>);
202219
break;
203220
case EnrichmentInfoType.InsufficientCredit:
204221
bars.push(<MessageBar messageBarType={MessageBarType.error} onDismiss={this._hideEnrichmentInfoMessage}>
205-
Could not auto-complete the company: not enough credits!
222+
{message}
223+
<br/>
206224
<Link href={info} target="_blank">
207225
Buy More
208226
</Link>
@@ -212,7 +230,7 @@ class Main extends React.Component<MainProps, MainState> {
212230
case EnrichmentInfoType.NotConnected_InternalError:
213231
case EnrichmentInfoType.Other:
214232
case EnrichmentInfoType.ConnectionError:
215-
bars.push(<MessageBar messageBarType={MessageBarType.error} onDismiss={this._hideEnrichmentInfoMessage}>{info}</MessageBar>);
233+
bars.push(<MessageBar messageBarType={MessageBarType.error} onDismiss={this._hideEnrichmentInfoMessage}>{message}</MessageBar>);
216234
break;
217235
}
218236
}

0 commit comments

Comments
 (0)