Due to the progression of B2B scenarios a new entity has been introduced - customer. Up to and including version 7.3, the term customer was incorrectly used. It was equivalent to user, and the corresponding cartridge bc_customer dealt with users. Now customers can be recognized as containers for users. An individual B2C customer contains only one user. A B2B customer may contain zero, one or many users. The contents of bc_customer was moved to bc_user, and bc_customer is now filled with different artifacts.
Customers are classified by type. The customer type is a simple property but it determines the structure of the customer. For example SMB
customers must support fields for taxation ID, company name, etc. New customer types can be added programatically.
The only difference with the previous version of the customer's concept and this document is the way the customer's references are kept with the order, in cases where a user of one business customer is moved to another business customer.
Have a look at the Cookbook - Customers for related questions.
Term | Meaning |
---|---|
SMB | Small and medium business |
Customer | A buying entity, container for users |
Customer type | A classification property for the customers In Intershop 7, customer types categorize customers. They indicate whether a customer represents:
Intershop 7's features can differ according to the customer type. For example, it can display either gross prices or net prices, provide additional profile information, hide certain functionality, etc. |
As the meaning of the term customer has changed (up to and including 7.3 the customer represented a user), the API of bc_customer and bc_customer_orm is not valid anymore. Within a refactoring process, bc_customer and bc_customer_orm were renamed/moved into bc_user and bc_user_orm. Artifacts that have the word "customer" in its name were renamed. Wherever the word "customer" did appear inside an artifact it was renamed as well.
To support B2B business scenarios new fields were added in BasicProfile, BasicAddress and StaticAddress:
Name | Table | Optional |
---|---|---|
Department | BasicProfile | |
PhoneHome | BasicProfile | |
PhoneBusiness | BasicProfile | |
PhoneMobile | BasicProfile | |
Fax | BasicProfile | |
BasicProfile | ||
CompanyName2 | BasicAddress | |
CompanyName2 | StaticAddress |
The customer type is a property that is required for any customer. The customer type is not only a classification but it also defines the internal structure of the customer. During the customer creation, the system creates various low-level artifacts (e.g., records in the database through the ORM layer) depending on the customer type. The figure below illustrates the flow on customer creation.
It is possible to enable/disable the login for customers of specific customer types for an application type. This can be done by using the intershop.application.login
property in share/system/config/apps/<application-type>/customerslogin.properties. Only customers that belong to one of the customer types added there can log in for applications of the configured application type. By default login is enabled for private customers in applications of type intershop.B2CWebShop
and for SMB customers in applications of type intershop.SMBWebShop
.
The processing of customers and customer data should be performed only through the BO layer ( bc_customer). All implementation details are hidden in the implementation cartridge (ORM based implementation bc_customer_orm). In order to be able to create new customer types and to use the BO layer, a knowledge of bc_customer is required. The cartridge is described below.
This section describes details about the artifacts contained in bc_customer.
CustomerBO
and its ExtensionsThe next figure shows the most important interfaces in the bc_customer cartridge.
The CustomerBO
interface is the basic container for customer data. Depending on the customer type, different business object extensions are available on the customer side. For example, the SMB
customers may return an instance of the CustomerBOCompanyCustomerExtension
. The same extension is not available in CustomerBO
s that represent individual customers. Based on the availability of the different extensions, different UI artifacts may be shown, for example.
The following extensions of CustomerBO
are available out of the box:
Extension | Description |
---|---|
CustomerBOCompanyCustomerExtension | Available for business customers. Provides accessors for various company properties like company name, taxation ID, etc. |
CustomerBODetailsExtension | Available for any customer. Provides accessors for common data that is implemented differently for the different customers. For example, the |
CustomerBOGroupCustomerExtension | Available for customers that may have more than one user. This extension may be used as |
CustomerBOPrivateCustomerExtension | Available only for individual customers. Contains accessor that returns the only user of this customer. |
The obvious question with this design is how do the CustomerBO
instances know which extension is available? The information is conveyed through the implementations of the CustomerType
interface, which is described below.
CustomerSegmentBO
The next figure shows the interfaces for a group of customers.
The CustomerSegmentBO
interface defines a customer segment - a group of customers. It is managed by the CustomerSegmentBORepository
. The repository itself manages the lifecycle of customer segment BO instances. For each assignment of content (CMS, promotions, shipping rules, prices), a customer segment is used.
CustomerType
InterfaceThe customer type interface describes a customer type. Customer types are wired to a CustomerTypeProvider
by the componentization framework, and they have no other form of persistence. The following methods are available within the interface:
public interface CustomerType { public String getCustomerTypeID(); public String getLocalizationKeyForName(); public boolean isApplicableExtension(String extensionID); }
The first two methods, getCustomerTypeID()
and getLocalizationKeyForName()
, are used for internal identification of the customer type and for displaying customer types to the end users. The last method decides which extension (described in the previous sections) is available for a customer. For example, here is the definition for the SMB
customer type:
<instance name="SMB_Customers" with="CustomerType" scope="app"> <fulfill requirement="customerTypeID" value="SMB" /> <fulfill requirement="localizationKeyForName" value="customertype.name.SMB_Customers" /> <fulfill requirement="applicableExtensionID" value="GroupCustomer" /> <fulfill requirement="applicableExtensionID" value="CompanyCustomer" /> </instance>
This definition implies that for customers with the type SMB
, applicable extensions besides CustomerBODetailsExtension
include the CustomerBOCompanyCustomerExtension
and the CustomerBOGroupCustomerExtension
. By default, the core product defines two customer types - individual and SMB. The next table shows the applicability of the extensions for each customer type.
Extension | Individual Customers | SMB Customers |
---|---|---|
CustomerBODetailsExtension | ||
CustomerBOPrivateCustomerExtension | ||
CustomerBOCompanyCustomerExtension | ||
CustomerBOGroupCustomerExtension |
CustomerBORepository
The customer BO repository may be retrieved in the context of the storefront applications directly from the ApplicationBO
, e.g., ApplicationBO:Repository("CustomerBORepository")
. Since both the users and the customers live in the anonymous organization, special application domain relations were added in the APPLICATIONDOMAINRELATION
table.
Each customer has a customer profile in BasicProfilePO
. This profile is used as bridge to legacy functionality such as address handling. You can easily spot the customer profile by checking the type code of each customer profile assignment, if it is equal to 3 (three) then this is the customer's profile. This relation however, cause unnecessary iteration over profile assignments of customer when common functionality such as addresses is required. To increase the performance CustomerPO
was denormalized with direct reference to customer's profile. However, it is not modeled as relation, but dependency. This means that resolving of the customer's profile is realized by using the ProfileMgr
, instead of ORM relation.
This section describes details about the artifacts contained in bc_user.
UserBO
and UserBORepository
The next figure shows the interfaces in the bc_user cartridge.
The next figure shows the persistence layer. Currently there is no distinction between business and "system" users. Therefore, the persistence layer for users and user related objects is defined in the core.
Note
The relation between addresses and profiles is not part of that figure. The API for addresses is contained within bc_address.
The import and export of users is enhanced. Customers are now part of it and they are the root container for users. In addition, the new properties of SMB
customers are a part of the export, like the taxation ID, company name etc.
The bc_customer and bc_user cartridges provide only a business API for processing customers and customer data. The actual implementation of customer specific functionality (e.g., ad-hoc UI in the storefront application for managing B2B details) should be achieved using extension points. The following figure illustrates the idea in the ISML layer.
The idea is that the functionality in the base cartridge is available to both the SMB
and the B2C
users. Within a specific cartridge, visible only to the SMB app, there are added extensions that will be active only when the SMB
app is browsed. The same applies to the B2C scenario. The "base" cartridge is sld_ch_b2c_app. This cartridge defines the extension points. The actual extension implementations are in the app_sf_webshop_smb cartridge.
A new attribute has been added to the user's profile, called e-mail. Although the attribute is not mandatory for all customer types, there are some that require it. Individual customers are one of those types, as well as the users of a group, or SMB ones. The administrator's ability to set a password for given users was revoked, and that is why this field became vital with regard to the login capabilities.
With the introduction of the customer's profile, there are now three locations were the e-mail related attribute is available. These are:
The reminder e-mail, which is part of the customer's (or a customer's users') credentials, is kept for compatibility and flexibility purposes. The reference application does not use it anymore.
The e-mail address stored with the customer's profile is used for any password-related e-mail activity. This includes:
The e-mails can be managed in two locations:
The customer is forced to use the e-mail as login. Therefore, with the registration, this e-mail is also propagated to the profile and the reminder e-mail. In the storefront, a customer may register with or without specifying address details, and using the address e-mail field is unsafe.
When customer is created in the Commerce Management application, the login and profile's e-mail attributes are shown as separate attributes, and their values may differ. The profile's e-mail address is propagated to the credential's reminder e-mail.
By splitting the user to customer and user, now there are two formats that are supported for user import - a legacy one and a new one. When the legacy format is imported, the following fallback applies in order to populate the profile's e-mail:
Following the order in this list, whichever imported attribute condition is met first, this attribute is used.
By introducing customers, a number of objects were introduced or renamed. This change affects objects on almost every application layer. The renaming can be summarized as follows:
The term consumer was renamed to customer, whenever it appears in the application.
The term consumer group was renamed to customer segment.
Now, instead of assigning a consumer to consumer group one will assign a customer to customer segment. There are some exceptions, though. The identifiers of customer segments are unique across a given domain and they are often used in custom projects to attach or modify certain aspects to/of the platform. For this reason, these identifiers are kept unchanged and thus, one will encounter a customer segment with, for example, the ID IG_RegisteredUsers
or IG_NewUsers
. The same applies to the price lists: The price list for all customers will still have the ID AllConsumersPriceList
.
Nevertheless, all texts throughout the sales channel applications do not mention the name consumer or consumer group anymore.
The table below lists the implicit customer segments available in the system. The segments are listed with its old name and description, i.e., when they were called consumer group. In addition, the two new implicit segments for individual and SMB customers are there as well.
ID | Name old | Description old | Name new | Description new |
---|---|---|---|---|
IG_NewUsers | New Consumers | Upon registration, consumers are automatically assigned to the group "New Consumers". Once registered consumers have placed their first order, return to the storefront in a different session and log on again (i.e., are identified by the system as registered user), they are removed from this group and assigned to "Recurring Consumers". | New Customers | All registered customers before they place their second order. Upon registration, customers are automatically assigned to the group "New Customers". Once registered customers have placed their first order, return to the storefront in a different session and log on again (i.e., are identified by the system as registered customers), they are removed from this group and assigned to "Recurring Customers". |
IG_RecurringUsers | Recurring Consumers | All registered consumers once they have placed their first order, return to the storefront in a different session and log on again (i.e., are identified by the system as registered user). | Recurring Customers | All registered customers once they have placed their first order, return to the storefront in a different session and log on again (i.e., are identified by the system as registered customers). |
IG_RegisteredUsers | Registered Consumers | All consumers who have registered and can be identified by the system as registered users. | Registered Customers | All customers who have registered and can be identified by the system as registered customer. |
IG_UnregisteredUsers | Unregistered Consumers | All consumers who have not registered yet or cannot be identified by the system as registered users. | Unregistered Customers | All customers who have not registered yet or cannot be identified by the system as registered customers. |
IG_PrivateCustomers | N/A | N/A | Individual Customers | All individual customers. Customers are automatically assigned to this customer segment based on their customer type. |
IG_SMBCustomers | N/A | N/A | SMB Customers | All small and medium business customers. Customers are automatically assigned to this customer segment based on their customer type. |
As explained in persistence of customer, every customer has a profile assignment. In order to persist the relation between a customer and a segment, a persistent assignment is created between the customer's profile itself and the corresponding user group, backing up the segment implementation.
That relation is enhanced for the group customers. In order for their users to get the full functionally of the storefront, like promotions, prices, CMS content, depending on the segments, all of their users are assigned.
Promotions for customers are realized via another segment assignment to a specific user group called target group (find more information in Overview - Promotions). Therefore, in order to keep this functionality, the customer's profile is assigned to the above mentioned target group, as with segments, in case where the customer is of group type and all customer's users share the same assignment. It is persisted both for the customer's profile and the user's profile.
By introducing customers another attribute is added to the orders and baskets - they are now aware of the customer that placed the order. If an individual customer checks out the basket, the user is the same as the customer. That is not the case if a user of a business customer does so. They buy on behalf on someone else, and that someone else is persisted when the order is placed. However, when moving the user to another customer, the reference at the order should be updated to correspond with the new assignment. This behavior has been introduced because of the possibility of "new customer self registration". As a consequence, some customers may need to be merged, their users may need to be moved to a single customer, and duplicate customers may need to be deleted.
This table lists the pipelines, used for implementing the new introduced customer:
Pipeline Name | Description |
---|---|
ProcessCustomer-GetCustomerByID | Returns CustomerBO by given CustomerBORepository and CustomerID. The CustomerID represents the UUID of the customer. |
ProcessCustomer-Create | Creates and returns CustomerBO by given CustomerBORepository, CustomerTypeID and CustomerNo. If there is no CustomerTypeID, the customer with the default customer type will be created. |
ProcessCustomer-Delete | First removes all users assigned to the customer (if there are any) and then deletes the customer. |
ProcessCustomer-Update | Updates the CustomerNo for the given customer. The pipeline does not return updated CustomerBO. |
ProcessCustomerAddress-CheckDeleteAddress | If the address is selected as preferred shipping or preferred billing address, it could not be deleted. The user should select another preferred billing or shipping address first. This is not valid if the simple registration is activated. The address will not be deleted if there is no other address for the customer. |
ProcessCustomerAddress-SetPreferredAddress | Sets the address as preferred shipping or preferred billing. |
ProcessCustomerAddress-UpdatePreferredAddress | Sets the given two addresses as preferred shipping and preferred billing. |
ProcessCustomers-Search | Searches customers by the given parameters. Returns iterator of customers |
ProcessCustomers-Delete | Deletes the customers from the given collection of customer IDs. First finds the customer by the UUID, then removes all users assigned to the customer (if there are any) and deletes the customer. |
ProcessCustomers-DeleteUsers | Deletes the users from the given collection of user IDs. First finds the customer of the user and checks if the customer is a group customer. Then gets the user by his UUID from the group customer and remove it. Otherwise the user will not be deleted. |
ProcessCustomerSegment-Search | Searches customer segments in the given domain. |
ProcessCustomerSegment-SearchAssignedCustomerBOs | Searches all customers assigned to the given customer segment. |
ProcessCustomerSegment-SearchUnassignedCustomerBOs | Searches all not assigned customers of the given customer segment. |
ProcessCustomerSegment-GetCustomerSegmentBO | Returns the customer segment by the given CustomerSegmentID, which represents the UUID of that customer segment. |
ProcessCustomerSegment-AddCustomerBOByID | Finds the customer by the given CustomerID and adds it to the customer segment. |
ProcessCustomerSegment-RemoveCustomerBOByID | Finds the customer by the given CustomerID and removes it from the customer segment. |
ProcessCustomerSegment-AddCustomerBO | Adds the CustomerBO to the given customer segment. |
ProcessCustomerSegment-RemoveCustomerBO | Removes the CustomerBO from the given customer segment. |
This table lists the pipelets, used for implementing the new introduced customer:
Pipelet Name | Description |
---|---|
AddCustomerBOToCustomerSegmentBO | Checks if the given customer is already assigned to the customer segment. If not, assigns it. |
CreateCustomerBO | Creates the customer in the given repository with the given CustomerNo and given CustomerTypeID. If the CustomerTypeID is not defined, the default customer type is used instead. |
CreateCustomerSegmentBO | Creates a CustomerSegmentBO with the given ID by the specified customer segment repository. |
DeleteCustomerBO | Deletes customer and the assigned users. |
DeleteCustomerSegmentBO | Deletes a customer segment by specified ID or CustomerSegmentBO. |
GetCustomerBO | Returns the customer to which the given user belongs. |
GetCustomerBOByID | Gets customer by the given ID for the specified customer repository. Returns error if none is found. |
GetCustomerBOByUserID | Finds the user from the UserBORepository and returns CustomerBO by the user that was found. |
GetCustomerSegmentBOByID | Retrieves a customer segment by the given ID for the specified customer segment repository. |
MoveUserBOToCustomerBO | Deletes all assignments of the user and assigns it to the given customer group. |
RemoveCustomerBOFromCustomerSegmentBO | Unassigns a specified CustomerBO from a specified CustomerSegmentBO (if it is already assigned). |
GetUserByCustomerBO | Returns the corresponding user for the given customerBO. |
GetCustomersForLastCutomerUserDeletion | Gets a collection of customer IDs for the last customer user deletion case, e.g., if after user deletion the customer has no assignments (users). |
GetUserBOsByCustomerID | Returns the corresponding users for the given customer. |
UpdateCompanyCustomerBO | Updates details that are specific to the company customers. |
UpdateCustomerBO | Updates the CustomerNo of the given customer. |
UpdateCustomerBOPreferredAddresses | Updates the preferred shipping and preferred billing address of the customer. |
UpdatePrivateCustomerBO | Updates individual customer's information with the provided parameters. |