Published
Thursday, August 27, 2009 - 09:42
Written by
We've been having quite a few requests for the ability to modify and extend the types of contact records which we can be stored in CiviCRM (currently limited to Individuals, Households and Organizations). Thanx to the nice folks at Alpha International, we will be adding the ability to rename or "hide" the existing Contact Types AND define Contact Sub-types as part of CiviCRM v3.1. Here is a first draft of what we plan to implement. Your comments and feedback are appreciated.

Contact Sub-types

In v3.1 we will introduce the notion of a Contact Sub-type. This will allow users to create specific types of Contacts for their use cases. For example, a school could introduce three new sub-types: Student, Parent and Staff. Sub-Types will inherit from one of the three contact types (Individuals in this case). Sub-types will have all the properties and features of the main contact types. Thus an admin will be able to:
  • Create a custom group that extends a specific sub-type. Thus all Student data can be extended with a set of student-specific custom fields. Custom fields defined for a specific sub-type can be viewed/edited for contacts of that sub-type (and conversely these fields are NOT included when viewing or editing other contacts).
  • Create a profile tailored for a specific sub-type. Thus a student directory will show properties of contacts who are students. A profile "create contact" form for a specific subtype will set the contact subtype appropriately.
  • Allow relationships to be created between specific contact sub-types. Thus a teacher <-> student relationship can be created where one contact is required to be of sub-type teacher while the other contact is required to be of sub-type student.
  • Allow the import/export mappings to reflect fields that belong to a specific sub-type.
  • Allow import of a file related to one contact sub-type only. Thus you can import only contacts of sub-type Student. Also allow import of the contact_type and contact_sub_type fields in a generic import (so you can included contacts of various types and sub-types in a single import file).
  • Allow overriding of the edit / view screens by contact subtype (similar to how we do template overrides for profile pages).
  • Add "create new..." menu entries for all sub-types, under the main contact type.

Implementation details

Contact Sub-types need to be extensible. We will use the civicrm_option_group and civicrm_option_value tables to store the Contact Type and Contact Sub-type information. Contact types will be stored in the option group 'contact_type'. The name will be the internal name used within the code (individual, household, organization etc). The label will be the value displayed to the user. Renaming is trivial and can be accomplished by changing the label of the option group. Hiding can be accomplished by setting the option group to be hidden. The contact sub-types will be stored in the option group: 'contact_subtype_typeName'. Each option group will have an entry for the default case (i.e. no contact subtype specified). Adding more contact sub-types for a specific contact type will simply mean adding a new option value entry. Adding a completely new contact type seems pretty feasible in this scheme. We will also need to store additional data as to what columns in civicrm_contact are applicable to this contact type, and which ones are required (for e.g. individual uses the first_name, last_name, gender_id etc). The required rules for individual are a bit more complex. Seems like this might be a good case to allow for extension via "hooks". In the table civicrm_contact the column contact_type is an enum. We need to change this to make it either a varchar or a integer (pointing to the option value for the contact type). For ease of implementation, i suspect we'll change it to a varchar and use the 'name' from the option_group_table. we also have a column in civicrm_contact for contact_sub_type (varchar). We could potentially store the name of the contact_sub_type or the option_value id. I suspect to keep things in sync with contact_type we will keep it as a string. If we do allow multiple sub types, we could store a comma separated string. I suspect a join table here might be a bit of a overkill

Other developments

  • During this development, we will also attempt to allow folks to hide or rename the main Contact Types. Thus an install can decide to hide the Household contact type and rename the Organization contact type to Team.
  • We currently are not planning to allow a contact to have multiple sub-types. We think that this will increase the complexity of the implementation significantly. However if it turns out to be not too hard, we might go down this route. If this is of interest to you, please consider sponsoring the functionality. We expect this feature to take an additional 50-100 hours at least
  • We currently do not plan on allowing new top level Contact types. However this might be a relatively easy feature when we restructure the code base to handle contact sub-types.
Filed under

Comments

Couple of items that are probably worthwhile adding:

- On the searches (basic, advanced), being able to filter by subtype (eg. search all the students)
- on the ACL being able to make visible only one type of content (might be through profiles ?). eg being able to list only the teachers, but not the students or parents.

basic and advanced search will have subtype support. Search builder will NOT have subtype support: http://issues.civicrm.org/jira/browse/CRM-5126

ACL support is on a group of contacts, and hence does not involve subtype :) Create a smart group with subtype teachers, and expose that etc

lobo

I have been hoping/waiting for this for some time now - I'm really looking forward to this!

We have looked at this internally and it very much seems to cover the ground that we need. Of course it is hard in the cold light of a blog post to know if we've covered all the bases. We will do some more thinking about use cases and post again if we come across something.

I think it is quite important to allow a contact to have multiple subtypes. For instance, a contact can be a volunteer and a donor at the same time. In this case, we will need to create 2 subtypes, each with its own set of custom fields.

P.S. If we want to sponsor the development of a new feature, what is the current hourly rate?

Thanks

our consulting agreement and rate sheet are on the wiki here:

http://wiki.civicrm.org/confluence/display/CRM/Consulting+Services+Agree...

if you think you can sponsor it, please let us know soon while we are designing and implementing it

lobo

Any rough idea of a schedule for 3.1? Adding sub-types is great news. It addresses the primary conceptual weakness in an otherwise excellent system. BTW I agree with not supporting multiple sub-types for a contact in the initial release. In my experience "multiple inheritance" as it were has innumerable subtleties and pitfalls. On the other hand, single inheritance would be nice. Can't tell from your description whether it's possible to create Student as a subtype of Individual, then GradStudent as a subtype of Student, or whether there will only be one level of subtyping. But one level will be better than none. :-)

on the innumerable subtleties and pitfalls of multiple inheritance - i'm interested.

thanks if so.

michael

It's been a while, and I will have to translate my memory of multiple inheritance complexities in the OOP world into the CiviCRM types world, so bear with me...but imagine the case where types A and B both have a custom field called X. Then type C derives from A and B. What is the meaning of X in the context of C? It is a solvable problem, but there are multiple possible solutions, and the code to enforce whatever solution the language architects choose gets nasty quickly. Just remembering how C++ implemented multiple inheritance rules makes me queasy :-).

Really pleased that this development is going ahead. Will be super useful.

Have you thought about letting custom data can apply to one or more contact types / subtypes?

At the moment, for example, I can't create some custom data that applies to organisations and households, but not to individuals. That might not seem like a huge problem but I have had a few clients where it would be really useful, and with the advent of content sub types it would be more so.

An example from activities (where you can define types might help illuminate). Lets say I've defined 10 different activity types and I have some custom data that applies to 5 of them. At the moment, I have to add this separately five times, or just apply it once to all activity types, and have it displayed on the 5 where it isn't actually applicable.

Changing the select to a checkbox/multi-select (and writing the code to back that up :) would be v. useful, no? Let me know what you think.

PS. Does this development have some wiki pages yet? / will it get some?

We'd like to get a minimal useful subset out there and working. Allowing custom groups to extend multiple different types of contacts / activities would be a separate project (and not related to this one). If i had to guess it would be another 100-200 hour project. Contract and rates on the wiki link above

Also for the first phase we'll only allow single one-level inheritance (i.e. u can only extend I/H/O)

hmm, not sure if we'll be putting any wiki pages. No plans as yet. If there is a need to, we will :)

lobo

I have posted at http://forum.civicrm.org/index.php/topic,9656.0.html about another need we have to be able to select which relationships custom fields would apply to, and a comment on this suggested being able to do theis for selected events and memberships. This is somewhat related to Michael's post, but as Lobo says is really a separate project subsequent to the initial sub-type delivery. We would be happy to be sponsoring this with others - maybe comments about this are best on the other forum post?
Marcus

Also, does it make sense to sneak in uses organisation address with these improvements? - I imagine you'll be making some changes to the uses household address if you are planning on being able to hide households (w00t!).

I'd be happy to round up the money if so - and you want to give me a steer on how much it would cost?

I really like the idea of being able to override edit/view. Currently it is very difficult to intermix fields from different regions of the Contact summary page (eg custom fields into core fieldsets, some core fields into custom field groups), which one of my clients thought was very important to help their users migrating from a legacy system. Also, would be very nice to be able to use profiles on the main contact / edit view rather than having all custom field groups and fields appear. As a default the latter might be fine, but sometimes it isn't appropriate.

This currently is not planned to be part of the subtype project. If you/your client would like to sponsor it, please contact us offline.

As of CiviCRM 4.1.0.