1
votes

I am new to not only C#, but also Microsoft Dynamics and I am having difficult accessing parent entity data of my Contact via a plug in. My goal is to auto fill my contact's address with the parent account address if the contact address fields are empty. I feel this is a relatively simple process that I am over complicating it.

public void SetContactAddress()
    {
        // TODO: Go and get the contact's parent account record and retrieve the 
        // address fields. Then update the contact's address with the fields from the
        // values from the account. Do not overrride the contact's address if one is provided/exists

        var item = _baseModel.TargetEntity as Entity;
        var parent = _baseModel.TargetEntity as Entity;

        Contact contact = new Contact(); //New blank contact in memory
        contact.Id = item.Id; //assign Id to the new local contact

        var service = _targetContact as IOrganizationService;


        Guid parentId = ((EntityReference)contact["new_parentid"]).Id;
        Entity parentEntity = service.Retrieve("new_parent", parentId, new ColumnSet(true)); //retrieve parent entity

        string[] addressAtrributes = {"Address1_City","Address1_Country","Address1_Line1","Address1_Line2",
                 "Address1_Line3", "Address1_PostalCode","Address1_StateOrProvince"};

        foreach (var key in parentEntity.Attributes.Keys)
        {
            if (addressAtrributes.Contains(key))
            {
                //contact.Address1_City = key;
                contact[key] = key;
            }
        }


        //contact.Address1_City = "My City"; //I can easily hard code a city in
            _baseModel.OrganizationService.Update(contact);

    }
3
What error are you getting?Aron
From business perspective your logic is wrong because if child address has only first line and parent address is completeley different and contains all three lines, your child will have it's own address and two lines from parent address which will make no sense. You should copy this fields only if all of them are empty, otherwise you are asking for a catastrophy in your system's data...Pawel Gradecki
I thought this was done automatically via mappings? For example, create your account, & set the address fields. Then create contacts for this account and the address fields should be populated. This is only for creates, not for updates. Then in that case I would use a workflow, not a pluginjasonscript

3 Answers

1
votes

First of all, you should change:

foreach (var key in parentEntity.Attributes.Keys)
{
    if (addressAtrributes.Contains(key))
    {
        //contact.Address1_City = key;
        contact[key] = key;
    }
}

To

foreach (var key in parentEntity.Attributes.Keys)
{
    if (addressAtrributes.Contains(key))
    {
        //contact.Address1_City = key;
        contact[key] = parentEntity[key];
    }
}

Because right now your code is assigning SchemaNames of addresss fields as values. And your list of attributes is wrong, they should be all lowercase. It's SchemaName that is camelcase, so you can go with:

contact.Address1_City //Address1_City is SchemaName, so name of column in DB

or

contact["address1_city"] //this is name of the field, you can check it in  Customizations area in Dynamics 365

The other way around it will not work. The list of address fields is overcomplication, better way (more maintaneable and easier to understand for the person reading code would simply be:

var parentContact = parentEntity.ToEntity<Contact>();
if(isAddressCloned) // you should only clone address if all the fields are empty, not cloning single fields if are empty
{
    contact.Address1_City = parentContact.Address1_City;
    contact.Address1_Country = parentContact.Address1_Country;
    //etc
}

As stated in other answer, this should be done on Pre-Create of contact, so contact should be your Target (you don't have it in your sample code, but I guess you have it somewhere in your plugin) and you should skip the last update in such case.

0
votes

Approach 1: (your approach)

I guess you are explicitly updating just created contact once again on post create plugin. That too code is incomplete like you are not checking empty address fields, not sure about assignment contact[key] = key;

Approach 2: (what I recommend)

on pre-create contact plugin, you can check address attributes of contact (target entity) for emptiness, then populate data for those fields in target entity itself from parent entity (custom account?) address fields retrieved.

targetEntity.Attributes["Address1_City"] = parentEntity["Address1_City"];

This way explicit update of contact can be avoided.

0
votes

My proposal would be to do this using workflows instead. There are workflow extensions you can get (for free) that will enable you to execute a workflow for all associated records (in this case an account's contacts).

Then just use a workflow to get the Account's address details and overwrite the contact's address.

I don't recommend a code-first approach for anything in CRM because it requires specialist knowledge to modify. If you use a workflow it can easily be modified; for example, maybe you also want to copy business phone and/or fax number.