I have created a custom CRM activity that I'm using in a workflow.
I'm using this activity as an InArgument to a custom workflow activity.
In the Execute() method I'm trying to set the OwnerId of the custom CRM activity instance to a system user and calling UpdateObject(entity) on the context object that I have generated using CrmSvcUtil.
[Input("Some name")]
[ReferenceEntity("mycustomactivity")]
[Required]
public InArgument<EntityReference> MyCustomActivity{get;set;}
void Execute(CodeActivityContext context)
{
IOrganizationService svc = context.GetExtension<IOrganizationService>();
var customActivityReference = MyCustomActivity.GetValue(MyCustomActivity);
//MyServiceContext is an OrganizationServiceContext generated using CrmSvcUtil
MyServiceContext servicecontext = new MyServiceContext(svc);
//GetCutomActivityInstance uses the Id to get an instance of the custom activity)
MyCustomCRMActivity activityInstance = GetCutomActivityInstance (servicecontext,customActivityReference.Id);
activityInstance.OwnerId = new EntityReference("systemuser",<SomeGUID>);
context.UpdateObject(activityInstance);
context.SaveChanges();
}
The above does not work, the activity owner is defaulting to my crm user account and is not updated to reflect the owner I'm setting in activityInstance.OwnerId
Any help would be much appreciated.
The owner can't be changed by update. You have to use the AssignRequest (or the built-in Assign-step, see screenshot)
See this answer https://stackoverflow.com/a/7746205/315862
Related
We're using the Run Project Billing screen to create records in AR / Invoice and Memo.
In the Invoice & Memo screen, we need the process to populate the header Customer Ord. number, along with a user field that has been added to the grid section on the 'Document Details' tab. At the moment, the process is not doing this.
I'd like to intercept the processing action on the screen using a technique I'm familiar with, namely using an 'AddHandler':
[PXOverride]
protected virtual IEnumerable Items (PXAdapter adapter)
{
PXGraph.InstanceCreated.AddHandler<BillingProcess>((graph) =>
{
graph.RowInserting.AddHandler<BillingProcess.ProjectsList>((sender, e) =>
{
//Custom logic goes here
});
});
return Base.action.Press(adapter);
}
I see no Base.Actions that remotely resembles 'Bill' or 'Bill All'.
This is obviously not exactly the code I need, but I would think this is the general place to start.
After reviewing the source business logic, I don't see any 'Bill' or 'Bill All' Actions - or any 'Actions' at all (baffling). I see an IEnumerable method called 'items', so that's what I started with above.
Is this the correct way to go about this?
Update: 2/14/2017
Using the answer provided re: the overridden method InsertTransaction(...) I've tried to set our ARTran user field (which is required) using the following logic:
PMProject pmproj = PXSelect<PMProject, Where<PMProject.contractID, Equal<Required<PMProject.contractID>>>>.Select(Base, tran.ProjectID);
if (pmproj == null) return;
PMProjectExt pmprojext = PXCache<PMProject>.GetExtension<PMProjectExt>(pmproj);
if (pmprojext == null) return;
ARTranExt tranext = PXCache<ARTran>.GetExtension<ARTranExt>(tran);
if (tranext == null) return;
tranext.UsrContractID = pmprojext.UsrContractID;
Even though this sets the user field to the correct value, it still gives me an error that the required field is empty when the process finishes. My limited knowledge prevents me from understanding why.
On the Run Project Billing screen, captions of Process and Process All buttons were changed to Bill and Bill All respectively in BLC constructor.
Process delegate is set for Items data view within the BillingFilter_RowSelected handler:
public class BillingProcess : PXGraph<BillingProcess>
{
...
public BillingProcess()
{
Items.SetProcessCaption(PM.Messages.ProcBill);
Items.SetProcessAllCaption(PM.Messages.ProcBillAll);
}
...
protected virtual void BillingFilter_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
BillingFilter filter = Filter.Current;
Items.SetProcessDelegate<PMBillEngine>(
delegate (PMBillEngine engine, ProjectsList item)
{
if (!engine.Bill(item.ProjectID, filter.InvoiceDate, filter.InvFinPeriodID))
{
throw new PXSetPropertyException(Warnings.NothingToBill, PXErrorLevel.RowWarning);
}
});
}
...
}
As code snippet above confirms, all records in the AR Invoice and Memos screen are created by instance of the PMBillEngine class. Below is code snippet showing how to override InsertNewInvoiceDocument and InsertTransaction methods within the PMBillEngine BLC extension:
public class PMBillEngineExt : PXGraphExtension<PMBillEngine>
{
public delegate ARInvoice InsertNewInvoiceDocumentDel(string finPeriod, string docType, Customer customer,
PMProject project, DateTime billingDate, string docDesc);
[PXOverride]
public ARInvoice InsertNewInvoiceDocument(string finPeriod, string docType, Customer customer, PMProject project,
DateTime billingDate, string docDesc, InsertNewInvoiceDocumentDel del)
{
var result = del(finPeriod, docType, customer, project, billingDate, docDesc);
// custom logic goes here
return result;
}
[PXOverride]
public void InsertTransaction(ARTran tran, string subCD, string note, Guid[] files)
{
// the system will automatically invoke base method prior to the customized one
// custom logic goes here
}
}
Run Project Billing process invokes InsertNewInvoiceDocument method to create new record on the AR Invoice and Memos screen and InsertTransaction method to add new invoice transaction.
One important thing to mention: overridden InsertNewInvoiceDocument and InsertTransaction methods will be invoked when a user launches Run Project Billing operation either from the processing Run Project Billing screen or from the data entry Projects screen.
For more information on how to override virtual BLC methods, see Help -> Customization -> Customizing Business Logic -> Graph -> To Override a Virtual Method available in every Acumatica ERP 6.1 website
I want to get the not modified entity when PostUpdate event triggered.
I try to use
context.PreEntityImages
but it is null.
How to I get this entity in PostUpdate event?
First, you need to register a pre-entityimage for the post-update step.
You can then acquire the entityimage using the following code snippet:
public void Execute(IServiceProvider serviceProvider)
{
var context = (IPluginExecutionContext) serviceProvider.GetService(typeof (IPluginExecutionContext));
Entity preImage = context.PreEntityImages.First().Value;
}
I am creating a plugin for Dynamics CRM 2011 to be executed when Qualifying a lead. I use this code
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(null);
Entity curEntity = (Entity)context.InputParameters["Target"];
but when I get the context.InputParameters["Target"] it says that key not found. How can I get the lead entity when qualifying a Lead?
If your plugin is executed on QualifyLead message (Lead as primary entity) you can get the reference to the lead in this way:
public void Execute(IServiceProvider serviceProvider)
{
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
if (context.InputParameters.Contains("LeadId") && context.InputParameters["LeadId"] is EntityReference)
{
EntityReference leadReference = (EntityReference)context.InputParameters["LeadId"];
Guid leadId = leadReference.Id;
// rest of your code
basically this message doesn't contain Target parameter, instead it contains LeadId parameter.
I needed the name of the entity precisely because my same custom workflow was getting triggered on workflow for two different entities. Thus identifying the Target was necessary until i found "PrimaryEntityName".
context.PrimaryEntityName could be used in case someone is looking to identify which target entity the workflow was triggered on
I am trying to populate a field in the system user entity whenever a user creates an account. I keep getting errors when trying to retrieve the system user entity so that I can populate its attributes. My code is as follows:
public void Execute(IServiceProvider serviceProvider)
{
ITracingService tracingservice = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.InitiatingUserId);
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
try
{
//Get entity that fired plugin
Entity entMain = (Entity)context.InputParameters["Target"];
//Make a String for the last activity entity
String strLastEntity = "";
//Make the entity for the user entity
Entity entUser = (Entity)service.Retrieve("systemuser", context.InitiatingUserId, new ColumnSet(new String[] { "new_lastactivityentity" }));
//Get the entity type that fired the plugin and set it to the right field for the user entity
if (entMain.LogicalName.Equals("account"))
{
strLastEntity = entMain.LogicalName;
entUser["new_lastactivityentity"] = strLastEntity;
}
}
catch (Exception ex)
{
tracingservice.Trace("FollowupPlugin: {0}", ex.ToString());
throw;
}
}
}
The error is:
Could not load file or assembly 'PluginRegistration, Version=2.1.0.1, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Can someone explain how to get the system user so I can update its attributes?
It is because you have an assembly reference that isn't installed on the server, in particular that is PluginRegistration.
You could place that dll in the GAC on the server, however this won't work for CRM Online (or in a Sandbox registration I believe).
Is PluginRegistration a reference to the Microsoft assembly used in the plugin registration tool? Generally speaking you don't need a reference to that in your project, so you could try removing the reference.
I am trying to add a event receiver on a list for itemadding. I have a field called EmployeeName people picker from which i need to get userprofile of that particular employee on item adding and trying to get EmployeeNo auto updated from userprofile.
I using as below: but not working
public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);
UserProfileManager profileManager = new UserProfileManager(context);
UserProfile myProfile = profileManager.GetUserProfile(item["EmployeeName"].ToString());
if (myProfile["EmployeeNo"].Value != null)
{
properties.AfterProperties["EmployeeNo"] = (myProfile["EmployeeNo"]).ToString();
}
item.Update();
}
Please help me on this.
Check if you use the correct internal column names.
Where do you get "item" from? Try using properties.ListItem instead.
Don't call properties.ListItem.update() (or item.update() in your code).