Last updated by clemens.tolboom on Tue, 2012-06-26 08:46
After many long discussions and a very well-attemted BoF at DrupalCon Copenhagen, here's how the CRM architecture is shaping up.
Some or most of these warrant further explanation...
Profile
This is based on the out-of-the-box way of doing user profiles in Drupal since the dawn of time. Administrators build profile type bundles, with field instances on them. Users can then create profile entities of those types, which they then own and become their personal profile data:

This diagram shows three (P) profile bundles, created by an administrator. They have field instances attached to them, depending on what the profile bundle is about.
Depending on the user's roles, they might only be able to create or edit certain profile types. This is analogous to D6's core content-type permissions:

Here we see an authenticated user who can create personal and contact (P) profile entities, but can't create a work profile entity (although an administrator could create it for them.) A second user, who has the "staff" user role, can create their own work profile entity themselves.
Note: profiles in D7 core are not based on Field API, so the project profile2 hopes to change that, with a view to becoming the core profile module for D8. This core requirement means that, even in profile2, profiles are not multiple for a particular user. This might therefore need a helper module, but that depends on use cases (see below.)
Technical stack
- entity API
- profile2
- profile_multiple: allows multiple instances of a profile type per user. (note: we may not need this, depends on use cases! opinions welcome.)
Party
P-a-r-t-why? Because we gotta!
A party is sort of a user without a user. It's a collection of profile objects tied to a single entity. Parties should be able to be dropped into an existing profile2 stack seamlessly.

There's only one type of party bundle, and it just acts as a bridge between a potentially non-existent user and a collection of profiles. Note that the party is always present, even if there's also a user. This helps us because then the CRM only needs to worry about parties and profiles, and not about a heterogeneous mix of parties-and-profiles and users-and-profiles.
Joachim is fleshing out the UI at the moment: it's going to be like editing a user account with the profile tabs, but without there being a user account present. This will hopefully be the common part to both CRM and DrupalCommerce, as these will be contacts /customers/constituents for CRM and customers for DrupalCommerce.
The party_user module within the same project will take care of connecting a party to a user when they match email addresses.
Technical stack
- Entity Relationship API: provides an API to connect entities.
- Party: create collections of profile2 objects to describe people, organizations etc. Think of this as all the data you can have about users, but without the user accounts.
- party_user: connects new users to existing parties using entity_relationship API. (probably bundled in with the party project)
- party_views: lets administrators and other users see cross-sections of parties, so that actions can be applied across many parties at once
- Views 3: dependency for party_views
- Views Bulk Operations: dependency for party_views
Genus
This is in some way the beating heart of CRM. It's also fairly abstract, so here's a detailed explanation.
Imagine a hierarchy of the types of contact in your CRM. You'd start with a generic contact. Below that, you have person and organization. Below those, whatever your application demands: in a school you might have staff, student, parent below person. In a charity, you might have staff, volunteer, donor. It's worth noting that one person recorded in your CRM could have belong to more than one of these.
Now for each genus (that's staff, student, charity, etc), define a standard list of fields. A staff party might have a payroll number field; a student a student number and emergency contact phone number, for instance.

The "developer" (G) genus bundle is like a die mould or stamp, stamping new fields onto an existing work (P) profile bundle to create a new type of work bundle.
A genus is abstract, but it can be applied to any bundle, either admixing in the fields with existing fields, or creating a new bundle. So in the CRM, we would apply them to a profile type, and get a new type we can use to build user/party profiles.
Note: because of limitations in D7 Field API, we have to apply genera bundles to profile bundles, not to individual profile entities. That means that, if we "enable" the "developer" genus bundle on the "work" profile type above, then in principle those new fields are available to be applied to all parties. We counteract this with a separate module, which allows administrators to moderate which active genera are efffectively visible for which parties:

Of these three parties: one has developer and staff genera available to them, so their payroll number and development team are "active"; one has designer and staff genera available to them but not developer, so while they don't see "dev team", they do see the payroll number and a link to their portfolio; the third is a completely different type of party, an external contact, who doesn't have payroll or any fields in common with the others - so they never see their "work" profile", but they do have an "sales" profile with other fields on it. Because they don't have "investor" ticked, the third user never sees the "(investment) amount" field.
Note that there's nothing special about applying this to profile bundles. If you wanted to build a directory of businesses you could apply different genera to nodes (eg company, restaurant, hotel) and get content types for these.
Technical stack
- genus: defines an extensible hierarchy of abstract types (eg person, staff, organization, charity) along with their field specification. These can then be mapped to create entity types with standard template fields. Defines extensible rules for creation of further types.
- genus_maintain: permit administrators to maintain genus
Activities
Activity log for interactions with a party, how it should relate to other parties and users. Also future events as separate objects but relating to previous activities
This needs discussion!
Technical stack
Here's the technical stack so far, in summary:
- genus: defines an extensible hierarchy of abstract types (eg person, staff, organization, charity) along with their field specification. These can then be mapped to create entity types with standard template fields. Defines extensible rules for creation of further types.
- party_user: connects new users to existing parties using entity_relationship API. (probably bundled in with the party project)
- party_views: lets administrators and other users see cross-sections of parties, so that actions can be applied across many parties at once
- entity_relationship API: provides an API to connect entities.
- party: create collections of profile2 objects to describe people, organizations etc. Think of this as all the data you can have about users, but without the user accounts.
- profile_multiple: allows multiple instances of a profile type per user. (note: we may not need this, depends on use cases! opinions welcome.)
- profile2
- entity API
- views3: dependency for party_views
-
views_bulk_operations: dependency for party_views
Ecosystem modules to follow:
- something to allow several users to control a party
(eg, for employees of an organization to all change its records)
- something to allow several users to control a party
Note that most of these remain to be written!
Further discussion
http://groups.drupal.org/node/90929
| Attachment | Size |
|---|---|
| drupal_crm_profile2_action.gif | 12.74 KB |
| drupal_crm_profile2_permissions.gif | 20.27 KB |
| drupal_crm_party_action.gif | 11.89 KB |
| drupal_crm_genus_action.gif | 14.27 KB |
| drupal_crm_genus_example_parties.gif | 27.64 KB |