I recommend reading the Resco documentation on plugin assemblies here to ensure proper project setup before coding.
In Resco CRM, you must create a new process and call it within the process to activate a plugin. See the example below:
Below is a plugin assembly I wrote that triggered specific logic upon creation of a new Price List. However, I encountered difficulty retrieving the current context of the newly created Price List. Instead, I passed in the Price List Guid and fetched the entity inside the code itself, which I implemented in the GetPriceList function.
Upon creation of a new Price List, we wanted to retrieve all active Products in the system. This was done in the GetAllProducts function. Then, new Price List Items were created and associated with the newly created Price List in the CreatePriceListItems function. In the final steps, any Accounts in the system which had the same Price List as my custom field ‘previouspricelist’ on the newly created Price List record were updated with the new Price List to ensure that the Accounts were up to date. Finally, existing Work Orders created between the start and end dates of the new Price List were updated in the UpdatePriceListsForWorkOrders function.
using System;
using System.Collections.Generic;
using System.Linq;
using XRMServer.Data;
using XRMServer.Data.Fetch;
using XRMServer.Plugin;
namespace Resco_Plugins
{
[PluginInputParameter("PriceListId", typeof(Guid), Required = true)]
public class PriceList_CreateNewPriceListItems : PluginBase
{
Guid UOM = new Guid("9cc3e32e-abed-454a-9fb6-b8e9c8209cff");
public override PluginResult Execute(IPluginExecutionContext context)
{
var service = context.GetService<IPluginOrganizationService>();
context.AppendLogLine("Service " + service);
var priceList = this.GetInputParameter<Guid>(context, "PriceListId");
context.AppendLogLine("priceList " + priceList);
IEntity PriceListEntity = GetPriceList(service, context, priceList);
List<IEntity> Products = GetAllProducts(service, context);
CreatePriceListItems(service, context, PriceListEntity, Products);
UpdatePriceListsForAccounts(service, context, PriceListEntity);
UpdatePriceListsForWorkOrders(service, context, PriceListEntity);
return PluginResult.Succeeded;
}
public IEntity GetPriceList(IPluginOrganizationService service, IPluginExecutionContext context, Guid priceList)
{
context.AppendLogLine("Entering GetPriceList function");
var fetch = new Fetch("pricelevel");
fetch.Entity.AddAttribute("id");
fetch.Entity.AddAttribute("name");
fetch.Entity.AddAttribute("percentage");
fetch.Entity.AddAttribute("begindate");
fetch.Entity.AddAttribute("enddate");
fetch.Entity.AddAttribute("previous_price_list");
fetch.Entity.AddAttribute("transactioncurrencyid");
fetch.Entity.Filter.Where("id", priceList);
var priceListResult = service.Fetch(fetch);
var priceListRecords = priceListResult.ToList();
var priceListRecord = priceListRecords[0];
context.AppendLogLine("Exiting GetPriceList function");
return priceListRecord;
}
public List<IEntity> GetAllProducts(IPluginOrganizationService service, IPluginExecutionContext context)
{
context.AppendLogLine("Entering GetAllProducts function");
var fetch = new Fetch("product");
fetch.Entity.AddAttribute("id");
fetch.Entity.AddAttribute("name");
fetch.Entity.Filter.Where("statecode", 0);
var productResult = service.Fetch(fetch);
var productResultRecords = productResult.ToList();
context.AppendLogLine("Exiting GetAllProducts function");
return productResultRecords;
}
public void CreatePriceListItems(IPluginOrganizationService service, IPluginExecutionContext context, IEntity PriceListEntity, List<IEntity> Products)
{
context.AppendLogLine("Entering CreatePriceListItems function");
foreach (var productRecord in Products)
{
var entity = service.NewInstance("productpricelevel");
entity.Add("name", productRecord["name"] + " - " + PriceListEntity["name"]);
entity.Add("productid", productRecord["id"]);
entity.Add("percentage", PriceListEntity["percentage"]);
entity.Add("pricingmethodcode", 2);
entity.Add("roundingoptioncode", 2);
entity.Add("roundingpolicycode", 4);
entity.Add("quantitysellingcode", 2);
entity.Add("amount", 0);
entity.Add("uomid", UOM);
entity.Add("pricelevelid", PriceListEntity["id"]);
entity.Add("transactioncurrencyid", PriceListEntity["transactioncurrencyid"]);
var result = service.Create(entity);
context.AppendLogLine("Price List Item with the Id '{0} was created.", result);
}
context.AppendLogLine("Exiting CreatePriceListItems function");
}
public void UpdatePriceListsForAccounts(IPluginOrganizationService service, IPluginExecutionContext context, IEntity PriceListEntity)
{
context.AppendLogLine("Entering UpdatePriceListsForAccounts function");
var fetch = new Fetch("account");
fetch.Entity.AddAttribute("id");
fetch.Entity.Filter.Where("defaultpricelevelid", PriceListEntity["previous_price_list"]);
var accountResult = service.Fetch(fetch);
var accountResultRecords = accountResult.ToList();
foreach (var accountRecord in accountResultRecords)
{
accountRecord["defaultpricelevelid"] = new EntityReference(PriceListEntity.Id, "pricelevel");
var result = service.Update(accountRecord);
context.AppendLogLine("Price List was updated for account.", result);
}
context.AppendLogLine("Exiting UpdatePriceListsForAccounts function");
}
public void UpdatePriceListsForWorkOrders(IPluginOrganizationService service, IPluginExecutionContext context, IEntity PriceListEntity)
{
context.AppendLogLine("Entering UpdatePriceListsForWorkOrders function");
var fetch = new Fetch("fs_workorder");
fetch.Entity.AddAttribute("id");
fetch.Entity.Filter.Where("pricelevelid", PriceListEntity["previous_price_list"]);
fetch.Entity.Filter.Between("createdon", PriceListEntity["begindate"], PriceListEntity["enddate"]);
var workrorderResult = service.Fetch(fetch);
var workrorderResultRecords = workrorderResult.ToList();
foreach (var workorderRecord in workrorderResultRecords)
{
workorderRecord["pricelevelid"] = new EntityReference(PriceListEntity.Id, "pricelevel");
var result = service.Update(workorderRecord);
context.AppendLogLine("Price List was updated for workorder.", result);
}
context.AppendLogLine("Entering UpdatePriceListsForWorkOrders function");
}
}
}
The purpose of this blog post is to guide developers on creating a new plugin in Resco CRM and demonstrate how to create, update, and retrieve data within a plugin assembly. I hope this information proves useful to you.