Defining a Customer Entity

I've been rereading some of my thoughts on orders and mulling over conversations with TR and gordon. We speculated on the need for a customer entity in Paris but didn't pursue it, instead placing a customer_uid field natively on order entities. However, we still didn't know the relationship between an e-mail address and an order, like Ubercart's $order->primary_email.

I think the obvious solution here is to define an additional customer entity that has a primary e-mail field and perhaps a primary user account uid field. Orders instead of referencing a customer_uid would then reference (or create) a customer, and for logged in users we can easily associate an order with an existing customer record based on primary uid.

The need for a customer entity is highlighted when thinking about interoperability. It's quite likely sites will not want Drupal user accounts for all their customers (this was actually a common but impossible scenario for Ubercart) but will want a common record against which to associate a person's orders. They would then tie this common record to a person / customer record in an external system.

I think we'll be best served by adding a "Customer" and "Customer UI" module to core, doing away with customer_uid on orders, and changing creator_uid to simply be uid and allow it to operate exactly like uid does on Products / Nodes (denoting ownership).

Ryan Szrama
Posted: May 21, 2010


matt2000 on May 21, 2010

Profile2 module will support collecting data for 'people' who may or may not be 'users.' So can I suggest that you create a 'Customer' profile (i.e., a FieldAPI 'bundle') instead of defining another new entity?

Ryan Ryan Szrama on May 22, 2010

My problem is that yes, it might "support" that, but it's far from what it's designed to do. The module is designed as a replacement for the core Profile module using entities and fields, and accordingly it's going to have a lot of cruft that simply won't be necessary here. Furthermore, depending on it would do the reverse of what we want to do in providing a separation between user accounts of the Drupal site and customer records that exist as a unique entity for the purpose of interacting with external systems. If everything is a Profile2 profile, meaning Drupal users who aren't customers, Drupal users who are customers, and customers who aren't Drupal users, there will be confusion in the concepts and UI.

Finally, I'm worried about yet another external dependency. It'd be one more moving piece that holds up Commerce, and that module's going to have to provide a comparable feature set and an upgrade path from the core Profile module before it is viable.

Also, fwiw, looking through Profile2's source code, it's currently still defining its own categories and fields just like the core Profile module.

redben on May 25, 2010

It clearly seems that choosing an approach over the other is going to add some inflexibility (but that could be fine though)
An other suggestions is to make the reference to The customer "configurable". Something like abstracting away the relation but having a default implementation (like the cutomer entity you suggest).
Meaning :
- I am on admin/commerce/settings/orders
- I have a field "Customer Entity to use" that lists the available entities (and eventually bundle types...)
Then i could choose Customer Entity (which might be the default commerce impl) or Profile or node or whatever. It just has to be an entity (and eventually a bundle type)
If you need a certain set of field to be present (think aspect or interface) this can be checked on validation (like address or name...)

Would this be complex ?

matt2000 on May 25, 2010

Would this be complex ?
ugh... not complex to implement probably, but it certainly makes the site builder experience more complex. I think I'd rather just have DC make it's own entity than add another abstract object relationship. CRM module can then take on the responsibility of deciding when data should come from a customer record, and when it should come from a profile record.

But, I don't see any reason that providing an upgrade path from core profile should inhibit our ability to decouple profiles from users. It's certainly not prohibited to have profile data loaded into the user object the way profile modules does now; it just becomes optional.

So please don't discount this possibility too quickly. And let me know if there's some kind of proof-of-concept demo that would allow you to get on board with the idea, and I'll see if I can work on it.

Ryan Ryan Szrama on May 25, 2010

My point about the upgrade path was more about what the purpose of a Profile2 entity is and how quickly that module will be production ready. The customer entity I'm envisioning is little more than a collection of references to other entities, whether it's a user account, a Profile2, or an external customer object.

I guess I need to hear a case for why doing this through Profile2 makes any sense other than it's already some abstract data assigned to users. : ?

matt2000 on May 25, 2010

I was told that TR commented recently that Drupal Commerce wouldn't be production-ready for 6mo to a year, so I doubt profile2 will be a cause of delay, if you choose to adopt it.

To answer your question, I'm just operating on the principle that it's bad to complicate a system with too many object types. An analogy might be, just as 'everything is a node', I'd suggest that 'everyone is a profile'.

To be more precise, 'everything' can be taken to mean, 'any kind of web content with a particular URL', and 'everyone' can be taken to mean 'any set of data that we know about a particular human in a particular context.'

But the basic principle is simple enough. Fewer entities yield greater interoperability of code, without the coders needing to know about all the possible uses cases. It's why so much magic can happen with 6,000 contrib modules that can assume everything is a node or a user.

I am thinking of this from the CRM side. For example, I want someone to be able to write a CRM reporting module that includes data about everyone who's interacted with the organization, online or offline, whether they have a user account or not, whether they've made a purchase or not. The idea is to be able to query and analyze 'profile' objects with complete agnosticism about where those objects came from. In the language of DB admin, we should not need to think about 'joins.' We just want to select 'people', not 'users AND customers AND contacts.'

We also want to avoid duplication of data. If someone adds their current telephone number to their 'customer information' that data should be available to any module that knows how to use the 'telephone number' field with needing to understand the 'customer entity.' Hopefully by Drupal 8, everyone will know how to use a profile entity, and that will be good enough.

fago (not verified) on May 28, 2010

>I guess I need to hear a case for why doing this through Profile2 makes any sense other than it's already some abstract data assigned to users. : ?

hey.. :)

profile2 supports non-user profiles, but provides no UI for that. Though doing so would be simple. Anyway I think it would make sense to add customer data as a profile2, because conceptually it makes sense to me. I think of the customer data of just an usual customer profile. And once the user signed up, you can associate it with the user.

Anyway, yes not much activity over there ;) I have not much time to care for it right now (writing on my thesis..), but I think we can flush it out pretty fast once the time has come (and entity forms have been fixed..) as we'll keep it simple nevertheless.

matt2000 on May 28, 2010

Providing the UI for non-user profiles may fall into the domain of CRM module (for which I am now a co-developer, with psynaptic), although if fago wants to put that in profile2, we'd be happy to oblige.

redben on May 26, 2010

Sorry if my comment was misunderstood. I'm not discounting anything. Just making a suggestions. By "Would this be complex" i meant "any thoughts ?" :)

As for the site builder experience, i suggested that Customer Entity would be a default handler. And only if needed the site builder would switch to some other defined entity.

"'everyone is a profile"
Well now i see what you mean.

So to adapt my suggestion to your proposal, replace Customer Entity as default implementation with Profile as default.

matt2000 on May 26, 2010

Now that I think about this, it provides some interesting possibilities. For example, imagine being able to decide that you want 'Customers' to be a node entity. Now we can use voting API/fivestar to vote on customers in an ebay feedback type use case.

Of course, the new D7 content_profile module is probably going to be nothing more than a node wrapper for profile entities, so that might be the clean way to do it, but the point is, now I can see the value in making customers any entity you might want.

It should be very doable if the reference fields on the customer entity are all FieldAPI fields, which are entity-type-agnostic by design.

redben on May 27, 2010

I do not want Customer Entity, neither do why want Profile. What i suggest is to give site builders the choice while providing a good default for a full featured out of the box solution. Now whether the default should be a customer entity or Profile2, i don't know :)
There are only a few things the commerce solution needs to know about a customer :
The customer must be "referenceable" (an id field)
The customer needs to have a name (a name field)
The customer must be contactable (address field, email, phone...)
For the rest, the commerce solution doesn't have to know where customers are stored and how, what other info it has...etc

So instead of commerce requiring a specific entity, it should only require any entity with a set of fields. like an interface in OOP or an aspect in AOP.

So instead of a hardcoded entity name for all customer related operation, you'd have a variable_get. Same thing for reporting and views.

Jason on May 27, 2010

There are only a few things the commerce solution needs to know about a customer :
The customer must be "referenceable" (an id field)
The customer needs to have a name (a name field)
The customer must be contactable (address field, email, phone...)
For the rest, the commerce solution doesn't have to know where customers are stored and how, what other info it has...etc

Agree with id field.
Agree with email/name field.

Rest doesn't need to be included, think about a commerce solution for a free event for a walk-a-thon. They don't need your address, phone, etc. Email is important and some reference id. The rest can be handled somewhere else.

matt2000 on May 28, 2010

I agree with redben, and Field API is very suited to this. DC defines what fields the entity must posses, and DC needs to be told which load function to call. Nothing more. In fact, the 'default' entity might as well be user since (a) it always exists, and (b) this could provide better backward compatibility with Ubercart.

4drian (not verified) on June 7, 2010

Surely there are a million and one use cases where a customer (i.e the entity that gets billed and where a delivery is made where relevant) is not just a named person. For my purposes, having a customer entity that is separate from users, either drupal accounts or not, makes a lot of sense as I would like to do B2B trade where several people or users are associated with a company (the customer). Ideally, this customer entity could also be made into a group (OG) and allow for a vast amount of flexibility in the future. This would then make tying up with external CRM, accounts package schemas much easier as most tend to separate the 'customer' from the named person or user. Please consider opening up Commerce to use cases other than B2C.

l0calh0rst on May 20, 2014

I would like to second that.
Currently I am fumbling with a B2B solution. Right now each user (multiple per company) gets ALL the available (predefined) profiles attached to it. This results in a giant redundancy as I cannot attach one profile to several users.
The customer entity might also allow to have superusers that would have access to several customer entities. A use case here is to have field staff supervising multiple customers.
Is there any progress on this?

mikeaja on May 21, 2014

I would have thought this is the ideal scenario for Organic Groups.

I'm not suggesting this will work 'as is', but I don't think B2B solutions such as this will be a priority in the Commerce development road map (I'm not sure about that, just my impression).

I do think this is a case of B2B people getting together here to help solve the issue. The way I would approach that is a new discussion with a very clear use case, that may attract others with the same issue to join in and find a solution.

mikeaja on May 21, 2014

I don't understand. I'm not ruling anything in or out. Maybe an important point with regards to community open-source projects is being missed here. This needs B2B interested people to get involved, suggest needed solutions and start to solve them, and contribute. That's how this gets done. Just like with Drupal.

For example, it seems the first stage is seeing what can be done with OG and reporting that.