Accessing multi-level fields in a CRM 2011 Workflow - workflow

Sorry if this is sort of confusing because I'm not sure how to word this. I am trying to create a workflow that runs off of Account's in Microsoft CRM 2011. One part of this workflow requires me to retrieve a field contained in the Business Unit of the User in the Account's "Created By" field. However, the workflow will only allow me to access the Business Unit itself, but not any of its fields.
I'm wondering if there is a simple trick or work-around that will allow me access to this data.
Thanks!
For reference, the Account has a User, who has a Business Unit, and the Business Unit has a field I need to access. CRM, however, doesn't want to let me get more than 2 levels deep when accessing fields.

Clunky but do-able if you accept a bit of denormalisation (temporarily or otherwise). I'll assume for the sake of example you want to get at the "cost centre" field from the BU.
Add a field on User entity to temporarily hold the value from the BU (so make it same type and length, text(100) in this case), optionally put it on the form.
Create a child workflow for the User entity to update the user with the "cost centre" value from their BU. Make it only available to run as a child, not onDemand or anything else. Activate
In your Account workflow, add a step to call the child workflow against the relevant user (eg Created By in your case).
Add a step to wait until the new cost centre field on the user record contains data.
Now do whatever you need to with the value from the user record, such as update the Account, or do some branched logic.
Whatever you do, once you have used the value, clear the field on the user record, or do this as the last step of the workflow.
Now, since Users don't change BU very often, you might actually just go ahead and keep that value on the User record permanently, and instead of a child workflow, simply run this on create of a new user, or on change of BU, and store the value permanently on the User record. Yes, it is 'denormalised' and not purest SQL design, but then you don't need a child workflow, you don't need a wait state and you don't have to clear the value at the end, or worry about what happens when two Accounts need to run their workflow at the same time. I include the more general approach above as this might apply to other records which do change their parent quite often.
Just an additional thought - you can access the "owning business unit" of the Account, but this will be the BU of the Owning User, rather than the Created By, but is your business process such that this would normally be the same person? (eg users only have Create priviledge to "user owned" depth, so can only create records they own).
If so, then you could get at the BU directly from the Account, and then any fields on it too (in a condition or to update the Account)
Alternative which is less ideal but a similar approach - add a relationship from Account to BU (eg "created BU"). Now you can update the Account with this by referring to the Created By User's BU, then in the next step, reference this value from the Account. This is again denormalised, and less preferable since number of Accounts is far greater than number of users, so the level of duplicate information is much higher.

You can't get deeper with the standard steps of a workflow.
The solution is to create a custom workflow activity, you can start from this article:
http://msdn.microsoft.com/en-us/library/gg328515.aspx

Related

Crm 2011 how to get the stepid in which the plugin is executing

In crm 2011, inside the Execute method of a plugin, how can I know the id of the registered step that is executing? For instance, I have two steps for the pre create of an account. The execute method will run two times one for each step. I need to know in the execute method the stepid of the step that is actually running. I can't find it in the context.
UPDATE:
I'm updating here to explain the scenario, because in the comments I don't have enough characters. So the scenario:
I have a solution for autonumbering entities that enables users to format their numbers the way they want.
For that I have an entity (autonumber) where they configure the format, the entity and the field they want to number. Every time a record is created for the autonumber entity it will create and register a step dynamically in the pre operation of the create message of the entity to be numbered, for example the account.
When that step is executed it will load the autonumber record to know how to number the account field.
The created step must be linked to the autonumber record and for that the autonumber entity has an attribute to store the id of the step. This attribute is filled on the pre create of the autonumber entity when the step is created.
This link attribute allows for the step to be unregistered when the user deletes the autonumber record because it knows exactly which step to unregister. It also allows the user to set the order in which the step is going to be executed if there are more plugins registered to the account.
The problem that I had was when I wanted to number 2 or more attributes for the same entity. In this case the users would create, lets say, 2 records of the autonumber entity in order to number 2 fields of the account. In this case I will have 2 steps registered to the account. When the account is being created one step will number one field and the other step will number the other field. That's why I need to know the id of the step that is being executed in order to load the right autonumber record.
Sorry for the tedious explanation but this scenario is a bit complex and I'm not sure if I was clear enough, but if you want I'll try to be more clear.
The OwningExtension property available on the IPluginExecutionContext will return an EntityReference to the SdkMessageProcessingingStep which should provide all the information you need.
What are you trying to achieve by registering the same plugin twice for the same Message and Stage? I'm struggling to think of a valid scenario.
You can get the name of the message from the context. Usually, I do something similar to this.
public void Execute(IServiceProvider serviceProvider)
{
IPlugingExecutionContext context
= (IPlugingExecutionContext)serviceProvider
.getService(typeof(IPlugingExecutionContext));
switch(context.MessageName)
{
case "Create" ExecuteCreate(); break;
case "Retrieve" ExecuteCreate(); break;
case "Update" ExecuteCreate(); break;
case "Delete" ExecuteCreate(); break;
default ExecuteFunctionality(Context.MessageName);
}
}
Then, of course, you need to implement those methods too. And usually I have a private field that hold the reference to context. It's good to be able to access it easily when the need arises. Also, you can (and should) check if the message is supported by your plug in, if there's a Target and if it's of the right entity type. Stuff like that.

CQRS - When a command cannot resolve to a domain

I'm trying to wrap my head around CQRS. I'm drawing from the code example provided here. Please be gentle I'm very new to this pattern.
I'm looking at a logon scenario. I like this scenario because it's not really demonstrated in any examples i've read. In this case I do not know what the aggregate id of the user is or even if there is one as all I start with is a username and password.
In the fohjin example events are always fired from the domain (if needed) and the command handler calls some method on the domain. However if a user logon is invalid I have no domain to call anything on. Also most, if not all of the base Command/Event classes defined in the fohjin project pass around an aggregate id.
In the case of the event LogonFailure I may want to update a LogonAudit report.
So my question is: how to handle commands that do not resolve to a particular aggregate? How would that flow?
public void Execute(UserLogonCommand command)
{
var user = null;//user looked up by username somehow, should i query the report database to resolve the username to an id?
if (user == null || user.Password != command.Password)
;//What to do here? I want to raise an event somehow that doesn't target a specific user
else
user.LogonSuccessful();
}
You should take into account that it most cases CQRS and DDD is suitable just for some parts of the system. It is very uncommon to model entire system with CQRS concepts - it fits best to the parts with complex business domain and I wouldn't call logging user in a particularly complex business scenario. In fact, in most cases it's not business-related at all. The actual business domain starts when user is already identified.
Another thing to remember is that due to eventual consistency it is extremely beneficial to check as much as we can using only query-side, without event creating any commands/events.
Assuming however, that the information about successful / failed user log-ins is meaningful I'd model your scenario with following steps
User provides name and password
Name/password is validated against some kind of query database
When provided credentials are valid RegisterValidUserCommand(userId) is executed which results in proper event
If provided credentials are not valid
RegisterInvalidCredentialsCommand(providedUserName) is executed which results in proper event
The point is that checking user credentials is not necessarily part of business domain.
That said, there is another related concept, in which not every command or event needs to be business - related, thus it is possible to handle events that don't need aggregates to be loaded.
For example you want to change data that is informational-only and in no way affects business concepts of your system, like information about person's sex (once again, assuming that it has no business meaning).
In that case when you handle SetPersonSexCommand there's actually no need to load aggregate as that information doesn't even have to be located on entities, instead you create PersonSexSetEvent, register it, and publish so the query side could project it to the screen/raport.

Creation Concurrency with CQRS and EventStore

Baseline info:
I'm using an external OAuth provider for login. If the user logs into the external OAuth, they are OK to enter my system. However this user may not yet exist in my system. It's not really a technology issue, but I'm using JOliver EventStore for what it's worth.
Logic:
I'm not given a guid for new users. I just have an email address.
I check my read model before sending a command, if the user email
exists, I issue a Login command with the ID, if not I issue a
CreateUser command with a generated ID. My issue is in the case of a new user.
A save occurs in the event store with the new ID.
Issue:
Assume two create commands are somehow issued before the read model is updated due to browser refresh or some other anomaly that occurs before consistency with the read model is achieved. That's OK that's not my problem.
What Happens:
Because the new ID is a Guid comb, there's no chance the event store will know that these two CreateUser commands represent the same user. By the time they get to the read model, the read model will know (because they have the same email) and can merge the two records or take some other compensating action. But now my read model is out of sync with the event store which still thinks these are two separate entities.
Perhaps it doesn't matter because:
Replaying the events will have the same effect on the read model
so that should be OK.
Because both commands are duplicate "Create" commands, they should contain identical information, so it's not like I'm losing anything in the event store.
Can anybody illuminate how they handled similar issues? If some compensating action needs to occur does the read model service issue some kind of compensation command when it realizes it's got a duplicate entry? Is there a simpler methodology I'm not considering?
You're very close to what I'd consider a proper possible solution. The scenario, if I may summarize, is somewhat like this:
Perform the OAuth-entication.
Using the read model decide between a recurring visitor and a new visitor, based on the email address.
In case of a new visitor, send a RegisterNewVisitor command message that gets handled and stored in the eventstore.
Assume there is some concurrency going on that, for the same email address, causes two RegisterNewVisitor messages, each containing what the system thinks is the key associated with the email address. These keys (guids) are different.
Detect this duplicate key issue in the read model and merge both read model records into one record.
Now instead of merging the records in the read model, why not send a ResolveDuplicateVisitorEmailAddress { Key1, Key2 } towards your domain model, leaving it up to the domain model (the codified form of the business decision to be taken) to resolve this issue. You could even have a dedicated read model to deal with these kind of issues, the other read model will just get a kind of DuplicateVisitorEmailAddressResolved event, and project it into the proper records.
Word of warning: You've asked a technical question and I gave you a technical, possible solution. In general, I would not apply this technique unless I had some business indicator that this is worth investing in (what's the frequency of a user logging in concurrently for the first time - maybe solving it this way is just a way of ignoring the root cause (flakey OAuth, no register new visitor process in place, etc)). There are other technical solutions to this problem but I wanted to give you the one closest to what you already have in place. They range from registering new visitors sequentially to keeping an in-memory projection of the visitors not yet in the read model.

How to get list of aggregates using JOliviers's CommonDomain and EventStore?

The repository in the CommonDomain only exposes the "GetById()". So what to do if my Handler needs a list of Customers for example?
On face value of your question, if you needed to perform operations on multiple aggregates, you would just provide the ID's of each aggregate in your command (which the client would obtain from the query side), then you get each aggregate from the repository.
However, looking at one of your comments in response to another answer I see what you are actually referring to is set based validation.
This very question has raised quite a lot debate about how to do this, and Greg Young has written an blog post on it.
The classic question is 'how do I check that the username hasn't already been used when processing my 'CreateUserCommand'. I believe the suggested approach is to assume that the client has already done this check by asking the query side before issuing the command. When the user aggregate is created the UserCreatedEvent will be raised and handled by the query side. Here, the insert query will fail (either because of a check or unique constraint in the DB), and a compensating command would be issued, which would delete the newly created aggregate and perhaps email the user telling them the username is already taken.
The main point is, you assume that the client has done the check. I know this is approach is difficult to grasp at first - but it's the nature of eventual consistency.
Also you might want to read this other question which is similar, and contains some wise words from Udi Dahan.
In the classic event sourcing model, queries like get all customers would be carried out by a separate query handler which listens to all events in the domain and builds a query model to satisfy the relevant questions.
If you need to query customers by last name, for instance, you could listen to all customer created and customer name change events and just update one table of last-name to customer-id pairs. You could hold other information relevant to the UI that is showing the data, or you could simply hold IDs and go to the repository for the relevant customers in order to work further with them.
You don't need list of customers in your handler. Each aggregate MUST be processed in its own transaction. If you want to show this list to user - just build appropriate view.
Your command needs to contain the id of the aggregate root it should operate on.
This id will be looked up by the client sending the command using a view in your readmodel. This view will be populated with data from the events that your AR emits.

Help with first Core Data project

This is my first project which I've encountered that I can't get by on NSUserDefaults peppered with some NSCoding protocol. I've been asked to write some POS software.
Essentially, the App needs to store a bunch of products, prices and sales accounts. The user should be able to add items and accounts, and track the balance of accounts over time. The balance of an account should be able to be carried over from one "Session" (time period) to the next.
I'm comfortable with the concepts, but I'd like to be confident that I'm modeling this right. Here's how I've modeled my data. I'd like to know if I've done this properly or if there are any glaring errors/omissions.
I've created an "Account" Entity, which has the following properties:
First Name
Last Name
Account ID
Group
There is a relationship to the transaction entity.
I've created an entity for each Session. Again, a session is just like a fiscal month. The session will have a custom name and an ID.
Session ID
Session Name
There is a relationship to all of the accounts that are applied to that session.
There are of course, products, which have a name and ID. There is also a relationship to the "price" object, so I can change the prices without affecting balances.
Please see this screenshot from Xcode 4 which explains my model in its entirety:
Edit:
Looking at this, it seems that I'm missing some important info, such as dates of transactions etc. That said, am I on the right track?
It has been my experience that point of sale transactions list all the data that is necessary to recreate the receipt in three tables, a header (think date of sale, singular tracking entity), a set of records for all items being sold (linking back to the sale header), and a set of records for all the methods of payment (again linked back to the sale header).
This will give you the opportunity to rebuild the individual transactions in the future. Also, this is a simplistic model, but should suffice for what you're asking. Nominally yo uwould also keep track of applied discounts on a per-line-item basis, and per-invoice discounts, and per-group discounts, and etc.
What's the relationship between sessions and transactions?
You probably don't need to have an entity for price, as it will likely just be a float. I'd recommend adding a price attribute to your product entity instead.
I don't know if transactions will need names or not, I suppose if you want to have notes then they should.
Also transactions should probably have a to-many relationship with products.
Will this be used on a single device or will there be many users? If each user (account) is responsible for its own data then it may make more sense to have transactions/session rather than transactions/user.