CRM 2011 – Nummerngenerierung (Laufnummer erzeugen)

Leider ein sehr leidiges Thema in der CRM-Entwicklung. Microsoft arbeitet mit GUIDs als Primärschlüssel, was einerseits natürlich sinnvoll ist, andererseits keinen „Schlüssel“ bzw. „Autowert“ zur Verfügung stellt, mit welchem man arbeiten kann. CRM bietet stattdessen die sog. „Automatische Nummerierung“ an. Leider hat diese Funktionalität einen riesen Haken: Die Funktionalität steht nur für die Entitäten Verträge, Anfragen, Angebote, Aufträge, Artikel, Rechnungen und Kampagnen zur Verfügung.

Bei einem größeren Projekt, z.B. wenn man komplett eigene Geschäftsprozesse, ist das natürlich ein wahnsinn. Keine Ahnung was Microsoft sich da hat einfallen lassen. Vermutlich kommt hier das übliche Argument zum tragen: „Für 95% der Kunden reicht’s aus. Wir wollen unseren Implementierungspartnern nicht die komplette Arbeit abnehmen.“. Naja, ich war noch nie ein großer Fan dieser Strategie…

Um das Problem zu lösen, habe ich eine eigene Entität erstellt, welche ich „Laufnummer“ genannt habe. Diese Entität hat keine Ansichten/Formulare, sie besitzt lediglich die Felder „neu_laufnummerid“ und „neu_nummer“.

Nachdem ich in meinen CRM-Projekten stark auf Webservices setze, habe ich eine Klasse zum Erzeugen der Laufnummer (nach Schema JJMMTT001) entwickelt, welche diese Nummer für den aktuellen Tag (in der Entität) sucht und ggf. hochzählt. Falls die Laufnummer (für diesen Tag) noch nicht generiert wurde, wird sie natürlich neu erzeugt:

[sourcecode language=“csharp“]
public class Laufnummer
{
public const string EntityName = "neu_laufnummer";
public const string EntityPrimaryKey = "neu_laufnummerid";

/// <summary>
/// Finds the highest verkaufsprojekt nummer.
/// </summary>
/// <param name="organization">The organization.</param>
/// <returns></returns>
public static string GetNew(contracts.IOrganization organization)
{
string laufNummer;
string suffix = StringHelper.FillLeftZero(1, 3);

QueryExpression query = new QueryExpression();
query.ColumnSet.AddColumns("neu_laufnummerid", "neu_nummer");
query.EntityName = EntityName;
query.AddOrder("neu_nummer", OrderType.Descending);
query.PageInfo = new PagingInfo();
query.PageInfo.Count = 1;
query.PageInfo.PageNumber = 1;

EntityCollection results = Helper.OrgService(organization).RetrieveMultiple(query);

if (results.Entities.Count > 0)
{
string lastNumber = results[0].Attributes["wit_nummer"].ToString();
if (lastNumber.Length < 9)
{
throw new InvalidProgramException("Die letzte Laufnummer war weniger als 9 Zeichen lang!");
}

string lastDayPattern = lastNumber.Substring(0, 6);
int lastCount = Convert.ToInt32(lastNumber.Substring(6, 3));
if (lastDayPattern == GetCurrentDayPattern())
{
lastCount++;
laufNummer = lastDayPattern + utils.StringHelper.FillLeftZero(lastCount, 3);
}
else
{
laufNummer = GetCurrentDayPattern() + suffix;
}

}
else
{
laufNummer = GetCurrentDayPattern() + suffix;
}

var entity = new Entity(EntityName);
entity.Attributes["neu_nummer"] = laufNummer;
EntityHelper.CreateEntity(organization, entity);

return laufNummer;
}

/// <summary>
/// Gets the current day pattern.
/// </summary>
/// <returns></returns>
public static string GetCurrentDayPattern()
{
return utils.StringHelper.FillLeftZero(Convert.ToInt32(DateTime.Now.Year.ToString().Substring(2, 2)), 2) +
utils.StringHelper.FillLeftZero(DateTime.Now.Month, 2) +
utils.StringHelper.FillLeftZero(DateTime.Now.Day, 2);
}
[/sourcecode]

Dieses Webservice kann man nun z.B. im OnSave-Event der Entität oder durch einen sonstigen Event triggern.
Viel Spaß beim Anwenden.

Cheers,
Chris

Leave a reply