dynamics-crm-2011custom-activity

CRM create CustomerAddress Programmatically


I am trying to make an activity that migrates an address from a lead to a contact. We do not use the default Address1 and Address2 in our CRM deployment (not my decision) so although the Qualification process does copy the address entered in the lead to the contact, it does so using the Address1 fields. I am using the code below, and everything seems to be working (no errors registering, no errors running the workflow that uses this activity). There's just one problem... nothing happens. Although there are no errors, no address gets created. I am running as the CRM admin so this shouldn't be a permissions thing, however even if it was shouldn't that generate a security exception? Any ideas why this is not working?

public class MigrateLeadAddressToContactActivity : CodeActivity
{
    [Input("Contact input")]
    [ReferenceTarget("contact")]
    public InArgument<EntityReference> InContact { get; set; }

    protected override void Execute(CodeActivityContext executionContext)
    {
        // Get the tracing service                         
        var tracingService = executionContext.GetExtension<ITracingService>();

        if (InContact == null)
        {
            const string errorMessage = "Contact was not set for Address Migration Activity";
            tracingService.Trace(errorMessage);
            throw new InvalidOperationException(errorMessage);
        }

        // Get the context service.                         
        var context = executionContext.GetExtension<IWorkflowContext>();
        var serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();

        // Use the context service to create an instance of CrmService.             
        var service = serviceFactory.CreateOrganizationService(context.UserId);

        //Retrieve the contact id
        var contactId = this.InContact.Get(executionContext).Id;

        // Get The Lead if it exists
        var query = new QueryByAttribute
                    {
                        ColumnSet = new ColumnSet(
                            new[]
                            {
                                "address1_line1",
                                "address1_line2",
                                "address1_line3",
                                "address1_city",
                                "address1_stateorprovince",
                                "address1_postalcode",
                                "address1_country",
                            }
                        ),
                        EntityName = "lead"
                    };

        // The query will retrieve all leads whose associated contact has the desired ContactId
        query.AddAttributeValue("customerid", contactId); 

        // Execute the retrieval.
        var results = service.RetrieveMultiple(query);

        var theLead = results.Entities.FirstOrDefault();
        if (null == theLead)
        {
            tracingService.Trace("Activity exiting... Contact not sourced from Lead.");
            return;
        }

        var newAddress = new Entity("customeraddress");
        newAddress.Attributes["name"] = "business";
        newAddress.Attributes["objecttypecode"] = "contact";
        newAddress.Attributes["addresstypecode"] = 200000;
        newAddress.Attributes["parentid"] = new CrmEntityReference("contact", contactId);
        newAddress.Attributes["line1"] = theLead.Attributes["address1_line1"];
        newAddress.Attributes["line2"] = theLead.Attributes["address1_line2"];
        newAddress.Attributes["line3"] = theLead.Attributes["address1_line3"];
        newAddress.Attributes["city"] = theLead.Attributes["address1_city"];
        newAddress.Attributes["stateorprovince"] = theLead.Attributes["address1_stateorprovince"];
        newAddress.Attributes["postalcode"] = theLead.Attributes["address1_postalcode"];
        newAddress.Attributes["country"] = theLead.Attributes["address1_country"];

        service.Create(newAddress);
        tracingService.Trace("Address Migrated from Contact to Lead.");
    }

Solution

  • Assuming there are indeed no exceptions thrown, the only other exit for that piece of code is here

    if (null == theLead)
    {
        tracingService.Trace("Activity exiting... Contact not sourced from Lead.");
        return;
    }
    

    So it would be fair to assume that theLead is null at this point and the workflow ends gracefully.

    To test this, throw an exception instead. Assuming the exception is throwm, you can investigate why it is null. Presumably, the value you are filtering on is not valid or not what you expect - or the field is empty.