serving the solutions day and night

Pages

Wednesday, March 30, 2016

MS Dynamics CRM - Generate Unique/Auto Number

MS Dynamics CRM doesn't contain auto increment number attribute. My client was assigned each unique registration number for contact entity.
There is lot options available in the market, but i used very easy code to achieve this task. I used pre create plugin operation to create new registration unique/auto number. Number will be create on while saving the record.

i created one custom entity (dns_global), it will keep last reg number.
Plugin Step
<Plugin Description="Auto Number" FriendlyName="AutoNumber" Name="DNS.VM.Plugins.AutoNumber" Id="00000000-0000-0000-0000-000000000000" TypeName="DNS.VM.Plugins.AutoNumber">
  <Steps>
    <clear />
    <Step CustomConfiguration="" Name="PreCreate" Description="Auto Number" Id="00000000-0000-0000-0000-000000000000" MessageName="Create" Mode="Synchronous" PrimaryEntityName="contact" Rank="1" SecureConfiguration="" Stage="PreInsideTransaction" SupportedDeployment="ServerOnly" />
  </Steps>
</Plugin>

Plugin Code
public class AutoNumber : Plugin
{
private static readonly object SyncLock = new object();

public AutoNumber()
   : base(typeof(AutoNumber))
{
   base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>(20, "Create", 'contact', new Action<LocalPluginContext>(ExecutePreCreate)));
}

/// Plugin steps:
/// create - contact - pre-operation - synchronous
/// </summary>
protected void ExecutePreCreate(LocalPluginContext localContext)
{
   if (localContext == null) throw new ArgumentNullException("localContext");

   IPluginExecutionContext context = localContext.PluginExecutionContext;
   IOrganizationService service = localContext.OrganizationService;

   if (context.InputParameters != null && context.InputParameters.Contains("Target"))
   {
Entity target = (Entity)context.InputParameters["Target"];
Entity img = (context.PreEntityImages != null && context.PreEntityImages.Contains("PreImage")) ? localContext.PluginExecutionContext.PreEntityImages["PreImage"] : null;

if (context.IsInTransaction) RegNumber(targetInputEntity, service);
             
   }
}

//Set Calling user System Admin, other wise global entity need write permission for calling user.
private void RegNumber(Entity entity, IOrganizationService service)
{
   lock (SyncLock)
   {
if (entity != null)
{
   string regnumber = RegNumberIncrement(service).ToString();
   if (regnumber!=null && regnumber!="0") entity['dns_regnumber'] = regnumber;
}
   }
        }

/*
* Generate new reg number.Get last reg number & increment 1,
* check the increment number not exist in contact reg number,
* otherwise loop it to find out next new reg number.
* update the new reg number to global entity and return number to the plugin.
*/
private int RegNumberIncrement(IOrganizationService crmService)
{
   XrmServiceContext con = new XrmServiceContext(crmService);
   int regnumber = 0;
   var gsv = con.dns_globalSet
    .Where(vh => (vh.dns_name == "REG NUMBER"))
    .Select(vh => new { vh.dns_Value, vh.dns_globalID }).FirstOrDefault();
   if (gsv != null)
   {
regnumber = Int32.Parse(gsv.dns_Value.ToString()) + 1;

//generate new number until find the new number
bool next = false;
while (!next)
{
   var c = con.ContactSet
.Where(vh => (vh.dns_RegNumber == regnumber.ToString()))
.Select(vh => vh.ContactId).FirstOrDefault();
   if (c == null)
   {
//if new number is not exist, create new number
dns_global egs = new dns_global()
{
   dns_globalID = gsv.dns_globalID,
   dns_Value = regnumber.ToString()
};
con.ClearChanges();
con.Attach(egs);
con.UpdateObject(egs);
con.SaveChanges();
next = true;
return regnumber;
   }
   else
   {
//if new number is  exist, incrment one untill new number
regnumber += 1;
   }
}
   }
   return regnumber;
        }

}

No comments: