skfd
skfd

Reputation: 2596

Copy PhoneCall `to` and `from` fields to the new PhoneCall

I'm making a button on PhoneCall ribbon that creates follow up call. I've tried to do this with javascript, with XrmServiceToolkit. Looks like I can't do it at all with SOAP end point and doing it with REST is some what tricky.

How do I copy to and from fields to a new activity?

Update Originally I tried using XrmServiceToolkit javascript library, but switched to C# for copying fields, following Peter's answer.

Still, no result. I do it this way:

EntityCollection toCollection = new EntityCollection();
foreach (var activityParty in ((EntityCollection)previousActivity["to"]).Entities)
{
    Entity newActivityParty = new Entity(ActivityParty.EntityLogicalName);
    newActivityParty["activityid"] = new EntityReference(context.PrimaryEntityName, context.PrimaryEntityId);
    newActivityParty["partyid"] = activityParty["partyid"];
    newActivityParty["participationtypemask"] = new OptionSetValue(2);//activityParty["participationtypemask"];
    //service.Create(newActivityParty);

    toCollection.Entities.Add(newActivityParty);
}
entity["to"] = toCollection;

What's the right way to do it?

Upvotes: 2

Views: 8155

Answers (3)

skfd
skfd

Reputation: 2596

Ended up doing it with JavaScript, after all:

function main() {
    var newActivity = new XrmServiceToolkit.Soap.BusinessEntity('phonecall');

    newActivity.attributes['phonecall'] = {
        id : Xrm.Page.data.entity.getId(),
        logicalName : 'phonecall',
        type : 'EntityReference'
    }

    newActivity.attributes['to'] = {
        type: 'EntityCollection',
        value: lookupToEntityReferenceCollection('to')
    }

    var newId = XrmServiceToolkit.Soap.Create(newActivity);
}

function lookupToEntityReferenceCollection(lookupName) {
    var result = [],
        lookupValue = Xrm.Page.getAttribute(lookupName).getValue();

    if (lookupValue === null) {return result;}

    var arrayLength = lookupValue.length;

    for (var i = 0; i < arrayLength;i++) {
        result.push({
            id: lookupValue[i].id, 
            logicalName: lookupValue[i].typename,
            type: 'EntityReference'
        });
    }
    return result;
}

Upvotes: 1

Peter Majeed
Peter Majeed

Reputation: 5362

Edit: On thinking this over, the most logically correct approach is as follows:

  1. Create a self-referential lookup field/relationship in the PhoneCall entity (the target of which is PhoneCall), called something like new_OriginatingCall. This will provide you your trail of follow up phone calls.
  2. Create a Create, pre-operation/validation plug-in on the PhoneCall entity that checks for the existence of a value in the new_OriginatingCall field. If it exists, populate the to and from fields from the originating PhoneCall.
  3. In the javascript attached to your button, create a new PhoneCall with the new_OriginatingCall populated.

This way, no matter how a follow-up call is generated, the to and from fields are always populated correctly server-side.

Edit: See below for a sample of how to retrieve and set PartyLists via Linq.

// newPc is the Target entity of the plugin.
var pc = xsc.PhoneCallSet
    .Single(x => x.ActivityId == newPc.new_OriginatingCall.Id);
// pc is now a copy of the original phone call.

// Have to make new activity party lists because the activity parties attached to
// the original phone call activity have the activity id set to the original
// phone call.
// Trying to attach them unchanged to the new phone call (which would have a new 
// activity id) results in a FaultException.
var to = pc.To.Select(x => new ActivityParty { PartyId = x.PartyId });
var from = pc.From.Select(x => new ActivityParty { PartyId = x.PartyId });

// Prep the new phone call.
PhoneCall pcNew = new PhoneCall
{
    To = to,
    From = from,
    Subject = pc.Subject,
    ActualDurationMinutes = pc.ActualDurationMinutes,
    DirectionCode = pc.DirectionCode,
    PhoneNumber = pc.PhoneNumber
};

// Create the new phone call.
service.Create(pcNew);

If you can more easily assemble PartyLists in .NET than in javascript, I strongly recommend using one of the two best answers suggested in the great question Call C# Code from Ribbon JScript CRM Online 2011 (i.e. trigger your code via the creation of a "plugin" custom entity or include a field in the PhoneCall entity that is set via javascript, and on update, triggers a plugin that examines the state of that field and reacts accordingly).

I've used both approaches often, as it's often complicated to achieve similar results in the CRM with javascript.

Upvotes: 1

David Spence
David Spence

Reputation: 8079

If you're finding it troublesome with JavaScript and you want a more front-end way of doing things, you could have a solution where you click your ribbon button which opens a new phone call form with the details you require pre-populated. You construct the URL with the parameters you require from your current form and this will set the values on your new form (your follow up phone call). Take a look at MSDN - Setting field values using paramaters.

You should be able to copy your to and from fields to the new form this way.

Note that this is an alternative. If you're wanting to completely automate the creation of the follow up phone call with JavaScript then I'd recommend using the REST endpoint and posting some code if you have difficulties.

Upvotes: 1

Related Questions