The process of mapping custom attributes in Microsoft Dynamics CRM Online from opportunity product to quote product to order product to invoice product is very similar in CRM Online to how it works in on-premise CRM.  There is just one problem that needs to be overcome, and that is getting the GUID for the entitymap entity from the CRM backend to plug into the URL to build the mapping
There are some issues that arise out of using CRM Online as you cannot access the SQL Server your instance resides on, this means you cannot easily get the GUIDs you need from the backend unless you use web services to retrieve them.  You must use a RetrieveMultiple call with SOAP in jscript or I usually use the 2007 (4.0) web services (which were also conveniently left in place for backward compatibility in CRM 2011).  I use the legacy endpoints because the soap envelopes are easily viewed in fiddler.  The other issue is that there is a minor change to the URL you need to use to access the custom mapping as CRM Online follows the IFD url structure for where the organization name is located.

1. First, you will need this jscript that you can attach to any entity form event in CRM to get the guid when that event is executed in order to retrieve the unique entitymapid for your organization to map from salesorderdetail (Order Product) to invoicedetail (Invoice Product).  Since this only needs to be done once, you can just attach it to an event and use the preview form function to retrieve the GUIDs and then remove the jscript without ever publishing it.

function testfunc()
{
//create SOAP envelope
var xmlSoapHeader= “” +
“<?xml version=\”1.0\” encoding=\”utf-8\”?>” +
“<soap:Envelope xmlns:soap=\”http://schemas.xmlsoap.org/soap/envelope/\” xmlns:xsi=\”http://www.w3.org/2001/XMLSchema-instance\” xmlns:xsd=\”http://www.w3.org/2001/XMLSchema\“>”;
var xmlAuthHeader = GenerateAuthenticationHeader();
var xmlSoapBody = “<soap:Body>” +
“<RetrieveMultiple xmlns=\”http://schemas.microsoft.com/crm/2007/WebServices\“> ” +
”    <query xmlns:q1=\”http://schemas.microsoft.com/crm/2006/Query\” xsi:type=\”q1:QueryByAttribute\” xmlns=\”http://schemas.microsoft.com/crm/2007/WebServices\“>” +
”      <q1:EntityName>entitymap</q1:EntityName>” +
”      <q1:ColumnSet xsi:type=\”q1:ColumnSet\”>” +
”        <q1:Attributes>” +
”          <q1:Attribute>entitymapid</q1:Attribute>” +
”          <q1:Attribute>sourceentityname</q1:Attribute>” +
”          <q1:Attribute>targetentityname</q1:Attribute>” +
”        </q1:Attributes>” +
”      </q1:ColumnSet>” +
” <q1:Attributes>” +
” <q1:Attribute>sourceentityname</q1:Attribute>” +
” </q1:Attributes>” +
” <q1:Values>”+
” <q1:Value xsi:type=\”xsd:string\”>salesorderdetail</q1:Value>” +
” </q1:Values>” +
”    </query>” +
” </RetrieveMultiple>” +
”  </soap:Body>” +
“</soap:Envelope>” +
“”;

var xmlt = xmlSoapHeader + xmlAuthHeader + xmlSoapBody;
var xmlHttpRequest = new ActiveXObject(“Msxml2.XMLHTTP”);
xmlHttpRequest.Open(“POST”, “/mscrmservices/2007/CrmService.asmx”, false);
xmlHttpRequest.setRequestHeader(“SOAPAction”,”http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple“);
xmlHttpRequest.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”);
xmlHttpRequest.setRequestHeader(“Content-Length”, xmlt.length);
xmlHttpRequest.send(xmlt);

}

2. Now run the form event you attached the jscript to.

If you use fiddler to capture your sessions, it will show you the needed entitymapid GUID quite nicely:

3.  Now you can piece together the URL for the mapping interface for the custom attribute mapping.  The syntax to use in CRM Online is:

https://myorgsubdomain.crm.dynamics.com/Tools/SystemCustomization/Relationships/Mappings/mappingList.aspx?mappingId=entitymapidGUID

Here is a syntax example using the guid above:

https://myspecialcrminstance.crm.dynamics.com/Tools/SystemCustomization/Relationships/Mappings/mappingList.aspx?mappingId=EB562CC6-991B-DF11-87A9-02BF0A0679DE

NOTE:  Since the GUIDs are unique to each organization of CRM, the GUID in the URL won’t actually work except in my own personal organization.

4. Navigate to the URL using your browser and below is the resulting screen.  You should see the familiar mapping dialog now for this normally non-accessible mapping.


That’s all there is to it, just add your mappings as needed.  If you need to get the other GUIDs for the other detail (product) entities in the sales process chain you just change the entity types in the script and re-run it.