There is no way for this to get applied natively, since the mapping takes place before the Lead Product is loaded, but the user doesn’t select a Product until after the Lead Product is loaded. There is however, a simple partial work around. Create a plugin that performs the mapping using what is defined in the OOB Field Mapping for the Relationship. For extensibility, define the parent field(s) in the plugin step. Below is a working example of such a plugin (utilizing the DLaB.Xrm.2016 NuGet Package).
public override void RegisterEvents() { RegisteredEvents.AddRange(new RegisteredEventBuilder(PipelineStage.PreOperation, MessageType.Create).Build()); } protected override void ExecuteInternal(ExtendedPluginContext context) { if (UnsecureConfig == null) { context.Trace("No Fields listed in the Unsecure Configuration. Nothing from which to initialize the entity!"); return; } var target = context.GetTarget<Entity>(); foreach (var field in UnsecureConfig.Split(new [] {",","|",Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)) { InitializeFromField(context, target, field); } } /// <summary> /// Loads the configured mappings for the entity from the given field. /// Only attributes that do not exist in the target are set, and only if the field contains an EntityReference in the target /// </summary> /// <param name="context">The context.</param> /// <param name="target">The target.</param> /// <param name="field">The field.</param> private void InitializeFromField(ExtendedPluginContext context, Entity target, string field) { context.TraceFormat("Initializing from field {0}", field); var parent = target.GetAttributeValue<EntityReference>(field); if (parent == null) { context.TraceFormat("No Parent found for field {0}", field); return; } var mappedEntity = context.SystemOrganizationService.InitializeFrom(parent, target.LogicalName, TargetFieldType.ValidForCreate); foreach (var att in mappedEntity.Attributes.Where(a => !target.ContainsAllNonNull(a.Key))) { context.TraceFormat("Adding attribute {0}:{1}", att.Key, att.Value); target.Attributes.Add(att); } }
The Details
- The Plugin must be registered for each entity to be initialized
- The Unsecure Configuration Settings must contain a comma (or pipe or newline) delimited list of parent lookup attributes to initialize the entity from. i.e. “ProductId”
- The parent field lookup field must be populated on the initial save.
- Only un-populated fields will be mapped. If a user has defined a value already, it will not be overridden.
- An end user will not see the mapped values on the form until after the initial save refresh occurs.
2 comments:
Hi,
Could you please tell me how to write Native pipeline?
Also Could you please give me more detail about the below line,
There is no way for this to get applied natively, since the mapping takes place before the Lead Product is loaded, but the user doesn’t select a Product until after the Lead Product is loaded.
Not sure what you mean by "write Native pipeline"
As far as your second question, the OOB Mapping functionality can't possibly work when selecting a parent entity from a child form, since the mapping takes place before the load of the form.
This post describes how you can create a plugin that will run on pre-create of the entity, and then manually performs the mapping. The difference to the user, is that they won't see the mapped values until after they first click save on the form.
Does that help?
Post a Comment